]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
buffer: modify inline memory ops to use packed structs
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 20 Aug 2015 23:31:25 +0000 (16:31 -0700)
committerSage Weil <sage@redhat.com>
Mon, 24 Aug 2015 20:52:45 +0000 (16:52 -0400)
packed structs can be used to ensure alignment is not an issue.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/include/inline_memory.h

index 6e08e420e535bf715887873c84cbbc1b3de1d616..65996f69bd676dee99b74890c7c51fa3ca319e24 100644 (file)
 #ifndef CEPH_INLINE_MEMORY_H
 #define CEPH_INLINE_MEMORY_H
 
-// only define these for x86_64 for now.
+#if defined(__GNUC__)
 
-#if defined(__GNUC__) && defined(__x86_64__)
-
-typedef unsigned uint128_t __attribute__ ((mode (TI)));
+typedef struct __attribute__((__packed__)) { uint16_t val; } packed_uint16_t;
+typedef struct __attribute__((__packed__)) { uint32_t val; } packed_uint32_t;
+typedef struct __attribute__((__packed__)) { uint64_t val; } packed_uint64_t;
 
 // optimize for the common case, which is very small copies
 static inline void maybe_inline_memcpy(char *dest, const char *src, size_t l,
@@ -34,17 +34,17 @@ void maybe_inline_memcpy(char *dest, const char *src, size_t l,
   }
   switch (l) {
   case 8:
-    *((uint64_t*)(dest)) = *((uint64_t*)(src));
+    ((packed_uint64_t*)dest)->val = ((packed_uint64_t*)src)->val;
     return;
   case 4:
-    *((uint32_t*)(dest)) = *((uint32_t*)(src));
+    ((packed_uint32_t*)dest)->val = ((packed_uint32_t*)src)->val;
     return;
   case 3:
-    *((uint16_t*)(dest)) = *((uint16_t*)(src));
+    ((packed_uint16_t*)dest)->val = ((packed_uint16_t*)src)->val;
     *((uint8_t*)(dest+2)) = *((uint8_t*)(src+2));
     return;
   case 2:
-    *((uint16_t*)(dest)) = *((uint16_t*)(src));
+    ((packed_uint16_t*)dest)->val = ((packed_uint16_t*)src)->val;
     return;
   case 1:
     *((uint8_t*)(dest)) = *((uint8_t*)(src));
@@ -69,6 +69,17 @@ void maybe_inline_memcpy(char *dest, const char *src, size_t l,
   }
 }
 
+#else
+
+#define maybe_inline_memcpy(d, s, l, x) memcpy(d, s, l)
+
+#endif
+
+
+#if defined(__GNUC__) && defined(__x86_64__)
+
+typedef unsigned uint128_t __attribute__ ((mode (TI)));
+
 static inline bool mem_is_zero(const char *data, size_t len)
   __attribute__((always_inline));
 
@@ -117,11 +128,7 @@ bool mem_is_zero(const char *data, size_t len)
   return true;
 }
 
-#else  // x86_64
-
-// on other architectures, default to something simple.
-
-#define maybe_inline_memcpy(d, s, l, x) memcpy(d, s, l)
+#else  // gcc and x86_64
 
 static inline bool mem_is_zero(const char *data, size_t len) {
   const char *end = data + len;