[prev in list] [next in list] [prev in thread] [next in thread]
List: uclibc-cvs
Subject: svn commit: trunk/uClibc: include/sys libc/stdlib/malloc
From: vapier () uclibc ! org (vapier at uclibc ! org)
Date: 2007-01-29 17:52:29
Message-ID: 20070129175229.CE86C485CF () busybox ! net
[Download RAW message or body]
Author: vapier
Date: 2007-01-29 09:52:29 -0800 (Mon, 29 Jan 2007)
New Revision: 17640
Log:
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.
Modified:
trunk/uClibc/include/sys/cdefs.h
trunk/uClibc/libc/stdlib/malloc/heap.h
trunk/uClibc/libc/stdlib/malloc/malloc.h
Changeset:
Modified: trunk/uClibc/include/sys/cdefs.h
===================================================================
--- trunk/uClibc/include/sys/cdefs.h 2007-01-29 17:10:19 UTC (rev 17639)
+++ trunk/uClibc/include/sys/cdefs.h 2007-01-29 17:52:29 UTC (rev 17640)
@@ -189,6 +189,14 @@
# define __attribute__(xyz) /* Ignore */
#endif
+/* We make this a no-op unless it can be used as both a variable and
+ a type attribute. gcc 2.8 is known to support both. */
+#if __GNUC_PREREQ (2,8)
+# define __attribute_aligned__(size) __attribute__ ((__aligned__ (size)))
+#else
+# define __attribute_aligned__(size) /* Ignore */
+#endif
+
/* At some point during the gcc 2.96 development the `malloc' attribute
for functions was introduced. We don't want to use it unconditionally
(although this would be possible) since it generates warnings. */
Modified: trunk/uClibc/libc/stdlib/malloc/heap.h
===================================================================
--- trunk/uClibc/libc/stdlib/malloc/heap.h 2007-01-29 17:10:19 UTC (rev 17639)
+++ trunk/uClibc/libc/stdlib/malloc/heap.h 2007-01-29 17:52:29 UTC (rev 17640)
@@ -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))
Modified: trunk/uClibc/libc/stdlib/malloc/malloc.h
===================================================================
--- trunk/uClibc/libc/stdlib/malloc/malloc.h 2007-01-29 17:10:19 UTC (rev 17639)
+++ trunk/uClibc/libc/stdlib/malloc/malloc.h 2007-01-29 17:52:29 UTC (rev 17640)
@@ -11,8 +11,13 @@
* Written by Miles Bader <miles at 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 @@
/* 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) \
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic