diff options
author | Quentin Armitage <quentin@armitage.org.uk> | 2010-03-24 12:26:46 -0500 |
---|---|---|
committer | Jeffrey C. Ollie <jeff@ocjtech.us> | 2010-03-24 12:26:46 -0500 |
commit | 4f1aa735c204d08b6022a99b01e97f3cd6c98c75 (patch) | |
tree | 8fc60c8a76a07a0c9e35dd4c96aa3bd17c48ee23 | |
parent | e909440a2abcdf1ed58810a20a7fd6a8f187816f (diff) | |
download | iksemel-fedora-1.4.tar.gz iksemel-fedora-1.4.tar.xz iksemel-fedora-1.4.zip |
Fix alignment on architectures where doubles are 64bit aligned, but pointers are smallerfedora-1.4
The tst-ikstack test fails on architectures where doubles are 64bit
aligned, but pointers are smaller, hence ppc, sparc and arm have the
problems.
The issue is that the ikstack and ikschunk structures are not
necessarily aligned to 64bits, and in fact ikschunk, with 32bit
pointers, is 20 bytes long, and hence not aligned.
The patch forces alignment of the two structures, and more importantly
makes the sizes of the structs multiples of the size of a double.
I have made a couple of other small changes:
i) The ALIGN macro for a pointer that was already aligned was adding
DEFAULT_ALIGNMENT bytes unnecessarily. The amendment also means
that the parameter to the macro is only processed once.
ii) The changing of char data[4] to char data[0] in the ikschunk
struct avoids a wasted allocation of 4 bytes.
-rw-r--r-- | src/ikstack.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/ikstack.c b/src/ikstack.c index bed4656..0ada246 100644 --- a/src/ikstack.c +++ b/src/ikstack.c @@ -7,25 +7,28 @@ #include "common.h" #include "iksemel.h" -struct align_test { char a; double b; }; +typedef double align_type ; +struct align_test { char a; align_type b; }; #define DEFAULT_ALIGNMENT ((size_t) ((char *) &((struct align_test *) 0)->b - (char *) 0)) #define ALIGN_MASK ( DEFAULT_ALIGNMENT - 1 ) #define MIN_CHUNK_SIZE ( DEFAULT_ALIGNMENT * 8 ) #define MIN_ALLOC_SIZE DEFAULT_ALIGNMENT -#define ALIGN(x) ( (x) + (DEFAULT_ALIGNMENT - ( (x) & ALIGN_MASK)) ) +#define ALIGN(x) ( ((x) + DEFAULT_ALIGNMENT - 1) & ~ALIGN_MASK ) typedef struct ikschunk_struct { struct ikschunk_struct *next; size_t size; size_t used; size_t last; - char data[4]; + align_type align[0] ; // Align data, and ensure struct size matches alignment + char data[0]; } ikschunk; struct ikstack_struct { size_t allocated; ikschunk *meta; ikschunk *data; + align_type align[0] ; // Ensure struct size matches alignment }; static ikschunk * |