Note: "permalinks" may not be as permanent as we would like,
direct links of old sources may well be a few messages off.
On Wed, Jun 17, 2009 at 09:32:59PM +0200, Lars Ellenberg wrote:
> On Wed, Jun 17, 2009 at 09:23:59PM +0200, Lars Ellenberg wrote:
> > maybe look at the assembler code generated.
>
> right. and also try without optimization.
I thought about it.
maybe the compiler deduces from "uint16_t *", that it would be aligned,
as any such point would need to be aligned on that architechture.
and decides to put aligned instructions there.
try this update, where I use (void*) for all ptr:
diff --git a/user/unaligned.h b/user/unaligned.h
index c55e8ef..4a8db42 100644
--- a/user/unaligned.h
+++ b/user/unaligned.h
@@ -1,79 +1,82 @@
#ifndef UNALIGNED_H
#define UNALIGNED_H
#include <stdint.h>
#if defined(__i386__) || defined(__x86_64__)
#define UNALIGNED_ACCESS_SUPPORTED
#endif
#ifndef UNALIGNED_ACCESS_SUPPORTED
#warning "Assuming that your architecture can not do unaligned memory accesses."
#warning "Enabling extra code for unaligned memory accesses."
#endif
#ifdef UNALIGNED_ACCESS_SUPPORTED
/* On some architectures the hardware (or microcode) does it */
#define get_unaligned(ptr) *(ptr)
#define put_unaligned(val, ptr) *(ptr) = (val)
#else
-/* on some architectures we have to do it in program code */
+/* On some architectures we have to do it in program code.
+ * memcpy() and no shifts, to avoid to distinguish between endianness.
+ * void *ptr, so the compiler does not make (wrong) assumptions
+ * about the alignment. */
-static inline uint16_t __get_unaligned_16(uint16_t *ptr)
+static inline uint16_t __get_unaligned_16(const void *ptr)
{
uint16_t rv;
memcpy(&rv, ptr, sizeof(rv));
return rv;
}
-static inline uint32_t __get_unaligned_32(uint32_t *ptr)
+static inline uint32_t __get_unaligned_32(const void *ptr)
{
uint32_t rv;
memcpy(&rv, ptr, sizeof(rv));
return rv;
}
-static inline uint64_t __get_unaligned_64(uint64_t *ptr)
+static inline uint64_t __get_unaligned_64(const void *ptr)
{
uint64_t rv;
memcpy(&rv, ptr, sizeof(rv));
return rv;
}
#define __bad_unaligned_access_size() ({ \
fprintf(stderr, "bad unaligned access. abort()\n"); \
abort(); \
})
-#define get_unaligned(ptr) ((typeof(*(ptr)))({ \
- __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
- __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_16((uint16_t *)(ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_32((uint32_t *)(ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_64((uint64_t *)(ptr)), \
- __bad_unaligned_access_size())))); \
+#define get_unaligned(ptr) ((typeof(*(ptr)))({ \
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_16((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_32((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_64((ptr)), \
+ __bad_unaligned_access_size())))); \
}))
#define put_unaligned(val, ptr) ({ \
- typeof(*ptr) v = val; \
+ typeof(*(ptr)) v = val; \
switch (sizeof(v)) { \
case 1: \
*(ptr) = v; \
break; \
case 2: \
case 4: \
case 8: \
- memcpy(ptr, &v, sizeof(v)); \
+ memcpy((void*)(ptr), &v, sizeof(v)); \
break; \
default: \
__bad_unaligned_access_size(); \
break; \
} \
(void)0; })
#endif
#endif
--
: Lars Ellenberg
: LINBIT | Your Way to High Availability
: DRBD/HA support and consulting http://www.linbit.com
DRBD® and LINBIT® are registered trademarks of LINBIT, Austria.
__
please don't Cc me, but send to list -- I'm subscribed