From: Martin Mares Date: Wed, 7 Mar 2001 13:38:19 +0000 (+0000) Subject: Created a new include for efficient access to unaligned data. X-Git-Tag: holmes-import~1516 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=79eebb222ecee1db69c22fe97e359cbcbb12fa8e;p=libucw.git Created a new include for efficient access to unaligned data. Updated fastbuf to use it. Removed sh_foff_t -- all modules should use sh_off_t instead (the only case where it would differ is the 2G--4G range of file sizes you get when LFS is turned on and LARGE_DB turned off and it's not interesting anyway) bgeto/bgetp selection is done in config.h. LFS is turned on by default. --- diff --git a/lib/config.h b/lib/config.h index 761751e3..64c2816b 100644 --- a/lib/config.h +++ b/lib/config.h @@ -13,9 +13,16 @@ /* Features */ -#undef SHERLOCK_CONFIG_LARGE_DB /* Support for DB files >4GB */ -#undef SHERLOCK_CONFIG_LFS /* Large files on 32-bit systems */ -#undef SHERLOCK_CONFIG_LFS_LIBC /* LFS supported directly by libc */ +#define SHERLOCK_CONFIG_LARGE_DB /* Support for DB files >4GB */ +#define SHERLOCK_CONFIG_LFS /* Large files on 32-bit systems */ +#define SHERLOCK_CONFIG_LFS_LIBC /* LFS supported directly by libc */ + +/* CPU characteristics */ + +#define CPU_LITTLE_ENDIAN +#undef CPU_BIG_ENDIAN +#define CPU_ALLOW_UNALIGNED +#define CPU_STRUCT_ALIGN 4 /* Paths */ @@ -43,28 +50,30 @@ typedef unsigned int sh_time_t; /* Timestamp */ typedef u32 oid_t; /* Object ID */ -#ifdef SHERLOCK_CONFIG_LFS /* off_t as passed to file functions */ -typedef s64 sh_off_t; -#define BYTES_PER_FILE_POINTER 5 -#else -typedef int sh_off_t; -#define BYTES_PER_FILE_POINTER 4 -#endif +/* Data types and functions for accessing file positions */ -#ifdef SHERLOCK_CONFIG_LARGE_DB /* off_t as present in database files */ -typedef s64 sh_foff_t; +#ifdef SHERLOCK_CONFIG_LARGE_DB +typedef s64 sh_off_t; +#define BYTES_PER_O 5 +#define BYTES_PER_P 8 +#define bgeto(f) bget5(f) +#define bputo(f,l) bput5(f,l) +#define bgetp(f) bgetq(f) +#define bputp(f,l) bputq(f,l) +#define GET_O(p) GET_U40(p) +#define GET_P(p) GET_U64(p) #else -typedef s32 sh_foff_t; +typedef s32 sh_off_t; +#define BYTES_PER_O 4 +#define BYTES_PER_P 4 +#define bgeto(f) bgetl(f) +#define bputo(f,l) bputl(f,l) +#define bgetp(f) bgetl(f) +#define bputp(f,l) bputl(f,l) +#define GET_O(p) GET_U32(p) +#define GET_P(p) GET_U32(p) #endif -/* CPU characteristics */ - -#define CPU_LITTLE_ENDIAN -#undef CPU_BIG_ENDIAN -#define CPU_CAN_DO_UNALIGNED_WORDS -#define CPU_CAN_DO_UNALIGNED_LONGS -#define CPU_STRUCT_ALIGN 4 - /* Misc */ #ifdef __GNUC__ diff --git a/lib/fastbuf.h b/lib/fastbuf.h index cd08fa8a..eb30d09c 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -11,6 +11,8 @@ #include #endif +#include "lib/unaligned.h" + /* * Generic buffered I/O on a top of buffer swapping functions. * @@ -107,16 +109,7 @@ static inline word bgetw(struct fastbuf *f) word w; if (f->bptr + 2 <= f->bstop) { - byte *p = f->bptr; -#ifdef CPU_CAN_DO_UNALIGNED_WORDS - w = * ((word *) p); -#else -#ifdef CPU_BIG_ENDIAN - w = (p[0] << 8) | p[1]; -#else - w = (p[1] << 8) | p[0]; -#endif -#endif + w = GET_U16(f->bptr); f->bptr += 2; return w; } @@ -130,16 +123,7 @@ static inline u32 bgetl(struct fastbuf *f) u32 l; if (f->bptr + 4 <= f->bstop) { - byte *p = f->bptr; -#ifdef CPU_CAN_DO_UNALIGNED_LONGS - l = * ((u32 *) p); -#else -#ifdef CPU_BIG_ENDIAN - l = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; -#else - l = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]; -#endif -#endif + l = GET_U32(f->bptr); f->bptr += 4; return l; } @@ -150,10 +134,10 @@ static inline u32 bgetl(struct fastbuf *f) u64 bgetq_slow(struct fastbuf *f); static inline u64 bgetq(struct fastbuf *f) { + u64 l; if (f->bptr + 8 <= f->bstop) { - u64 l; - memcpy(&l, f->bptr, 8); + l = GET_U64(f->bptr); f->bptr += 8; return l; } @@ -167,12 +151,7 @@ static inline u64 bget5(struct fastbuf *f) u64 l; if (f->bptr + 5 <= f->bstop) { - byte *p = f->bptr; -#ifdef CPU_BIG_ENDIAN - l = ((u64)p[0] << 32) | (u32)((p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]); -#else - l = ((u64)p[4] << 32) | (u32)((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); -#endif + l = GET_U40(f->bptr); f->bptr += 5; return l; } @@ -185,18 +164,7 @@ static inline void bputw(struct fastbuf *f, word w) { if (f->bptr + 2 <= f->bufend) { - byte *p = f->bptr; -#ifdef CPU_CAN_DO_UNALIGNED_WORDS - * ((word *) p) = w; -#else -#ifdef CPU_BIG_ENDIAN - p[0] = w >> 8U; - p[1] = w; -#else - p[1] = w >> 8U; - p[0] = w; -#endif -#endif + PUT_U16(f->bptr, w); f->bptr += 2; } else @@ -208,22 +176,7 @@ static inline void bputl(struct fastbuf *f, u32 l) { if (f->bptr + 4 <= f->bufend) { - byte *p = f->bptr; -#ifdef CPU_CAN_DO_UNALIGNED_LONGS - * ((u32 *) p) = l; -#else -#ifdef CPU_BIG_ENDIAN - p[0] = l >> 24U; - p[1] = l >> 16U; - p[2] = l >> 8U; - p[3] = l; -#else - p[3] = l >> 24U; - p[2] = l >> 16U; - p[1] = l >> 8U; - p[0] = l; -#endif -#endif + PUT_U32(f->bptr, l); f->bptr += 4; } else @@ -235,7 +188,7 @@ static inline void bputq(struct fastbuf *f, u64 l) { if (f->bptr + 8 <= f->bufend) { - memcpy(f->bptr, &l, 8); + PUT_U64(f->bptr, l); f->bptr += 8; } else @@ -247,21 +200,7 @@ static inline void bput5(struct fastbuf *f, u64 l) { if (f->bptr + 5 <= f->bufend) { - byte *p = f->bptr; - u32 low = l; -#ifdef CPU_BIG_ENDIAN - p[0] = l >> 32U; - p[1] = low >> 24U; - p[2] = low >> 16U; - p[3] = low >> 8U; - p[4] = low; -#else - p[4] = l >> 32U; - p[3] = low >> 24U; - p[2] = low >> 16U; - p[1] = low >> 8U; - p[0] = low; -#endif + PUT_U40(f->bptr, l); f->bptr += 5; } else @@ -333,22 +272,4 @@ int bdirect_read(struct fastbuf *f, byte **buf); int bdirect_write_prepare(struct fastbuf *f, byte **buf); void bdirect_write_commit(struct fastbuf *f, byte *pos); -/* Depending on compile-time configuration, we select the right function for reading/writing of file offsets */ - -#ifdef SHERLOCK_CONFIG_LARGE_DB -#define bgeto(f) bget5(f) -#define bputo(f,l) bput5(f,l) -#define bgetp(f) bgetq(f) -#define bputp(f,l) bputq(f,l) -#define FASTBUF_BYTES_PER_O 5 -#define FASTBUF_BYTES_PER_P 8 -#else -#define bgeto(f) bgetl(f) -#define bputo(f,l) bputl(f,l) -#define bgetp(f) bgetl(f) -#define bputp(f,l) bputl(f,l) -#define FASTBUF_BYTES_PER_O 4 -#define FASTBUF_BYTES_PER_P 4 -#endif - #endif diff --git a/lib/unaligned.h b/lib/unaligned.h new file mode 100644 index 00000000..83593145 --- /dev/null +++ b/lib/unaligned.h @@ -0,0 +1,41 @@ +/* + * Sherlock Library -- Fast Access to Unaligned Data + * + * (c) 1997--2001 Martin Mares + */ + +#ifndef _SHERLOCK_UNALIGNED_H +#define _SHERLOCK_UNALIGNED_H + +#ifdef CPU_ALLOW_UNALIGNED +#define GET_U16(p) (*((u16 *)(p))) +#define GET_U32(p) (*((u32 *)(p))) +#define GET_U64(p) (*((u64 *)(p))) +#define PUT_U16(p,x) *((u16 *)(p)) = (x) +#define PUT_U32(p,x) *((u32 *)(p)) = (x) +#define PUT_U64(p,x) *((u64 *)(p)) = (x) +#else +#define GET_U64(p) ({ u64 _x; memcpy(&_x, p, 8); _x; }) +#define PUT_U64(p,x) do { u64 _x=x; memcpy(p, &_x, 8); } while(0) +#ifdef CPU_BIG_ENDIAN +#define GET_U16(p) (((p)[0] << 8) | (p)[1]) +#define GET_U32(p) (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | (p)[3]) +#define PUT_U16(p,x) (void)(((p)[0] = ((x) >> 8)), (((p)[1]) = (x))) +#define PUT_U32(p,x) (void)(((p)[0] = ((x) >> 24)), (((p)[1]) = ((x) >> 16)), (((p)[2]) = ((x) >> 8)), (((p)[3]) = (x))) +#else +#define GET_U16(p) (((p)[1] << 8) | (p)[0]) +#define GET_U32(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0]) +#define PUT_U16(p,x) (void)(((p)[1] = ((x) >> 8)), (((p)[0]) = (x))) +#define PUT_U32(p,x) (void)(((p)[3] = ((x) >> 24)), (((p)[2]) = ((x) >> 16)), (((p)[1]) = ((x) >> 8)), (((p)[0]) = (x))) +#endif +#endif + +#ifdef CPU_BIG_ENDIAN +#define GET_U40(p) (((u64) (p)[0] << 32) | GET_U32((p)+1)) +#define PUT_U40(p,x) do { (p)[0] = ((x) >> 32); PUT_U32(((p)+1), x); } while(0) +#else +#define GET_U40(p) (((u64) (p)[4] << 32) | GET_U32(p)) +#define PUT_U40(p,x) do { (p)[4] = ((x) >> 32); PUT_U32(p, x); } while(0) +#endif + +#endif