diff options
| author | Mike Frysinger <vapier@gentoo.org> | 2007-01-29 17:52:29 +0000 | 
|---|---|---|
| committer | Mike Frysinger <vapier@gentoo.org> | 2007-01-29 17:52:29 +0000 | 
| commit | 3e0a1f38828a309fda3e9b89bb2e9ffa5ba6387d (patch) | |
| tree | 0a5b1459b5c9a5d738434662a36992407b8470c6 /libc/stdlib | |
| parent | c5db1d4612f80820cdf2123674c6771892ef5ea9 (diff) | |
| download | uClibc-alpine-3e0a1f388.tar.bz2 uClibc-alpine-3e0a1f388.tar.xz | |
Richard Sandiford writes:
However, retesting on m68k showed up a problem that had appeared in
uClibc since the last time I tried.  Specifically, revision 15785 did:
  -#define HEAP_GRANULARITY       (sizeof (HEAP_GRANULARITY_TYPE))
  +#define HEAP_GRANULARITY       (__alignof__ (HEAP_GRANULARITY_TYPE))
  -#define MALLOC_ALIGNMENT       (sizeof (double))
  +#define MALLOC_ALIGNMENT       (__alignof__ (double))
The problem is that
  (a) MALLOC_HEADER_SIZE == MALLOC_ALIGNMENT
  (b) the header contains a size value of type size_t
  (c) sizeof (size_t) is 4 on m68k, but...
  (d) __alignof__ (double) is only 2 (the largest alignment used on m68k)
So we only allocate 2 bytes for the 4-byte header, and the least
significant 2 bytes of the size are in the user's area rather than
the header.  The patch below fixes that problem by redefining
MALLOC_HEADER_SIZE to:
  MAX (MALLOC_ALIGNMENT, sizeof (size_t))
(but without the help of the MAX macro ;)).  However, we really would
like to have word alignment on Coldfire.  It makes a big performance
difference, and because we have to allocate a 4-byte header anyway,
what wastage there is will be confined to the end of the allocated block.
Any wastage will also be limited to 2 bytes per allocation compared to
the current alignment.
I've therefore used the __aligned__ type attribute to create a double
type that has at least sizeof (size_t) bytes of alignment.  I've
introduced a new __attribute_aligned__ macro for this.  It might seem
silly protecting against old or non-GNU compilers here, but the extra
alignment is only an optimisation, and having the macro is more in the
spirit of the other attribute code.
Diffstat (limited to 'libc/stdlib')
| -rw-r--r-- | libc/stdlib/malloc/heap.h | 2 | ||||
| -rw-r--r-- | libc/stdlib/malloc/malloc.h | 18 | 
2 files changed, 14 insertions, 6 deletions
| diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h index 23358d988..ecc432b8e 100644 --- a/libc/stdlib/malloc/heap.h +++ b/libc/stdlib/malloc/heap.h @@ -25,7 +25,7 @@  /* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY.     HEAP_GRANULARITY must be a power of 2.  Malloc depends on this being the     same as MALLOC_ALIGNMENT.  */ -#define HEAP_GRANULARITY_TYPE	double +#define HEAP_GRANULARITY_TYPE	double __attribute_aligned__ (sizeof (size_t))  #define HEAP_GRANULARITY	(__alignof__ (HEAP_GRANULARITY_TYPE)) diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h index 747e8bf9e..78232d62d 100644 --- a/libc/stdlib/malloc/malloc.h +++ b/libc/stdlib/malloc/malloc.h @@ -11,8 +11,13 @@   * Written by Miles Bader <miles@gnu.org>   */ -/* The alignment we guarantee for malloc return values.  */ -#define MALLOC_ALIGNMENT	(__alignof__ (double)) +/* The alignment we guarantee for malloc return values.  We prefer this +   to be at least sizeof (size_t) bytes because (a) we have to allocate +   that many bytes for the header anyway and (b) guaranteeing word +   alignment can be a significant win on targets like m68k and Coldfire, +   where __alignof__(double) == 2.  */ +#define MALLOC_ALIGNMENT \ +  __alignof__ (double __attribute_aligned__ (sizeof (size_t)))  /* The system pagesize... */  extern size_t __pagesize; @@ -98,17 +103,20 @@ extern int __malloc_mmb_debug;  /* The size of a malloc allocation is stored in a size_t word -   MALLOC_ALIGNMENT bytes prior to the start address of the allocation: +   MALLOC_HEADER_SIZE bytes prior to the start address of the allocation:       +--------+---------+-------------------+       | SIZE   |(unused) | allocation  ...   |       +--------+---------+-------------------+       ^ BASE             ^ ADDR -     ^ ADDR - MALLOC_ALIGN +     ^ ADDR - MALLOC_HEADER_SIZE  */  /* The amount of extra space used by the malloc header.  */ -#define MALLOC_HEADER_SIZE	MALLOC_ALIGNMENT +#define MALLOC_HEADER_SIZE			\ +  (MALLOC_ALIGNMENT < sizeof (size_t)		\ +   ? sizeof (size_t)				\ +   : MALLOC_ALIGNMENT)  /* Set up the malloc header, and return the user address of a malloc block. */  #define MALLOC_SETUP(base, size)  \ | 
