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