]> mj.ucw.cz Git - libucw.git/commitdiff
Created a new include for efficient access to unaligned data.
authorMartin Mares <mj@ucw.cz>
Wed, 7 Mar 2001 13:38:19 +0000 (13:38 +0000)
committerMartin Mares <mj@ucw.cz>
Wed, 7 Mar 2001 13:38:19 +0000 (13:38 +0000)
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.

lib/config.h
lib/fastbuf.h
lib/unaligned.h [new file with mode: 0644]

index 761751e3da822a65bca75cafc815cbeb40653587..64c2816bd43d1a56283bedcbb27e7e1628a1ed1a 100644 (file)
 
 /* 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__
index cd08fa8a9b88839800729f81cde5141850d2cbd8..eb30d09cf0a38d98faa40799f49b290cd11e6c29 100644 (file)
@@ -11,6 +11,8 @@
 #include <stdio.h>
 #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 (file)
index 0000000..8359314
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *     Sherlock Library -- Fast Access to Unaligned Data
+ *
+ *     (c) 1997--2001 Martin Mares <mj@ucw.cz>
+ */
+
+#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