OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[uclinux-h8/uClibc.git] / libc / stdlib / malloc / malloc.h
1 /*
2  * libc/stdlib/malloc/malloc.h -- small malloc implementation
3  *
4  *  Copyright (C) 2002  NEC Corporation
5  *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
6  *
7  * This file is subject to the terms and conditions of the GNU Lesser
8  * General Public License.  See the file COPYING.LIB in the main
9  * directory of this archive for more details.
10  *
11  * Written by Miles Bader <miles@gnu.org>
12  */
13
14 /* The alignment we guarantee for malloc return values.  */
15 #define MALLOC_ALIGNMENT        (sizeof (double))
16
17 /* The system pagesize... */
18 extern size_t __pagesize;
19 libc_hidden_proto(__pagesize)
20 #define MALLOC_PAGE_SIZE        __pagesize
21
22 /* The minimum size of block we request from the the system to extend the
23    heap for small allocations (we may request a bigger block if necessary to
24    satisfy a particularly big request).  */
25 #define MALLOC_HEAP_EXTEND_SIZE MALLOC_PAGE_SIZE
26
27 /* When a heap free-area grows above this size, try to unmap it, releasing
28    the memory back to the system.  */
29 #define MALLOC_UNMAP_THRESHOLD  (8*MALLOC_PAGE_SIZE)
30 /* When unmapping a free-area, retain this many bytes if it's the only one,
31    to avoid completely emptying the heap.  This is only a heuristic -- the
32    existance of another free area, even if it's smaller than
33    MALLOC_MIN_SIZE, will cause us not to reserve anything.  */
34 #define MALLOC_MIN_SIZE         (2*MALLOC_PAGE_SIZE)
35
36 /* When realloc shrinks an allocation, it only does so if more than this
37    many bytes will be freed; it must at at least HEAP_MIN_SIZE.  Larger
38    values increase speed (by reducing heap fragmentation) at the expense of
39    space.  */
40 #define MALLOC_REALLOC_MIN_FREE_SIZE  (HEAP_MIN_SIZE + 16)
41
42
43 /* For systems with an MMU, use sbrk to map/unmap memory for the malloc
44    heap, instead of mmap/munmap.  This is a tradeoff -- sbrk is faster than
45    mmap/munmap, and guarantees contiguous allocation, but is also less
46    flexible, and causes the heap to only be shrinkable from the end.  */
47 #ifdef __ARCH_HAS_MMU__
48 # define MALLOC_USE_SBRK
49 #endif
50
51
52 /* The current implementation of munmap in uClinux doesn't work correctly:
53    it requires that ever call to munmap exactly match a corresponding call
54    to mmap (that is, it doesn't allow you to unmap only part of a
55    previously allocated block, or to unmap two contiguous blocks with a
56    single call to munmap).  This behavior is broken, and uClinux should be
57    fixed; however, until it is, we add code to work around the problem in
58    malloc.  */
59 #ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
60
61 /* A structure recording a block of memory mmapped by malloc.  */
62 struct malloc_mmb
63 {
64   void *mem;                    /* the mmapped block */
65   size_t size;                  /* its size */
66   struct malloc_mmb *next;
67 };
68
69 /* A list of all malloc_mmb structures describing blocsk that malloc has
70    mmapped, ordered by the block address.  */
71 extern struct malloc_mmb *__malloc_mmapped_blocks;
72
73 /* A heap used for allocating malloc_mmb structures.  We could allocate
74    them from the main heap, but that tends to cause heap fragmentation in
75    annoying ways.  */
76 extern struct heap __malloc_mmb_heap;
77
78 /* Define MALLOC_MMB_DEBUGGING to cause malloc to emit debugging info about
79    about mmap block allocation/freeing by the `uclinux broken munmap' code
80    to stderr, when the variable __malloc_mmb_debug is set to true. */
81 #ifdef MALLOC_MMB_DEBUGGING
82 # include <stdio.h>
83 extern int __putc(int c, FILE *stream) attribute_hidden;
84
85 extern int __malloc_mmb_debug;
86 # define MALLOC_MMB_DEBUG(indent, fmt, args...)                               \
87    (__malloc_mmb_debug ? __malloc_debug_printf (indent, fmt , ##args) : 0)
88 # define MALLOC_MMB_DEBUG_INDENT(indent)                                      \
89    (__malloc_mmb_debug ? __malloc_debug_indent (indent) : 0)
90 # ifndef MALLOC_DEBUGGING
91 #  define MALLOC_DEBUGGING
92 # endif
93 #else /* !MALLOC_MMB_DEBUGGING */
94 # define MALLOC_MMB_DEBUG(fmt, args...) (void)0
95 # define MALLOC_MMB_DEBUG_INDENT(indent) (void)0
96 #endif /* MALLOC_MMB_DEBUGGING */
97
98 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
99
100
101 /* The size of a malloc allocation is stored in a size_t word
102    MALLOC_ALIGNMENT bytes prior to the start address of the allocation:
103
104      +--------+---------+-------------------+
105      | SIZE   |(unused) | allocation  ...   |
106      +--------+---------+-------------------+
107      ^ BASE             ^ ADDR
108      ^ ADDR - MALLOC_ALIGN
109 */
110
111 /* The amount of extra space used by the malloc header.  */
112 #define MALLOC_HEADER_SIZE      MALLOC_ALIGNMENT
113
114 /* Set up the malloc header, and return the user address of a malloc block. */
115 #define MALLOC_SETUP(base, size)  \
116   (MALLOC_SET_SIZE (base, size), (void *)((char *)base + MALLOC_HEADER_SIZE))
117 /* Set the size of a malloc allocation, given the base address.  */
118 #define MALLOC_SET_SIZE(base, size)     (*(size_t *)(base) = (size))
119
120 /* Return base-address of a malloc allocation, given the user address.  */
121 #define MALLOC_BASE(addr)       ((void *)((char *)addr - MALLOC_HEADER_SIZE))
122 /* Return the size of a malloc allocation, given the user address.  */
123 #define MALLOC_SIZE(addr)       (*(size_t *)MALLOC_BASE(addr))
124
125
126 /* Locking for multithreaded apps.  */
127 #ifdef __UCLIBC_HAS_THREADS__
128
129 # include <pthread.h>
130
131 # define MALLOC_USE_LOCKING
132
133 typedef pthread_mutex_t malloc_mutex_t;
134 # define MALLOC_MUTEX_INIT      PTHREAD_MUTEX_INITIALIZER
135
136 # ifdef MALLOC_USE_SBRK
137 /* This lock is used to serialize uses of the `sbrk' function (in both
138    malloc and free, sbrk may be used several times in succession, and
139    things will break if these multiple calls are interleaved with another
140    thread's use of sbrk!).  */
141 extern malloc_mutex_t __malloc_sbrk_lock;
142 #  define __malloc_lock_sbrk()  __pthread_mutex_lock (&__malloc_sbrk_lock)
143 #  define __malloc_unlock_sbrk() __pthread_mutex_unlock (&__malloc_sbrk_lock)
144 # endif /* MALLOC_USE_SBRK */
145
146 #else /* !__UCLIBC_HAS_THREADS__ */
147
148 /* Without threads, mutex operations are a nop.  */
149 # define __malloc_lock_sbrk()   (void)0
150 # define __malloc_unlock_sbrk() (void)0
151
152 #endif /* __UCLIBC_HAS_THREADS__ */
153
154
155 /* branch-prediction macros; they may already be defined by libc.  */
156 #ifndef likely
157 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
158 #define likely(cond)    __builtin_expect(!!(int)(cond), 1)
159 #define unlikely(cond)  __builtin_expect((int)(cond), 0)
160 #else
161 #define likely(cond)    (cond)
162 #define unlikely(cond)  (cond)
163 #endif
164 #endif /* !likely */
165
166
167 /* Define MALLOC_DEBUGGING to cause malloc to emit debugging info to stderr
168    when the variable __malloc_debug is set to true. */
169 #ifdef MALLOC_DEBUGGING
170
171 extern void __malloc_debug_init (void);
172
173 /* The number of spaces in a malloc debug indent level.  */
174 #define MALLOC_DEBUG_INDENT_SIZE 3
175
176 extern int __malloc_debug, __malloc_check;
177
178 # define MALLOC_DEBUG(indent, fmt, args...)                                   \
179    (__malloc_debug ? __malloc_debug_printf (indent, fmt , ##args) : 0)
180 # define MALLOC_DEBUG_INDENT(indent)                                          \
181    (__malloc_debug ? __malloc_debug_indent (indent) : 0)
182
183 extern int __malloc_debug_cur_indent;
184
185 /* Print FMT and args indented at the current debug print level, followed
186    by a newline, and change the level by INDENT.  */
187 extern void __malloc_debug_printf (int indent, const char *fmt, ...);
188
189 /* Change the current debug print level by INDENT, and return the value.  */
190 #define __malloc_debug_indent(indent) (__malloc_debug_cur_indent += indent)
191
192 /* Set the current debug print level to LEVEL.  */
193 #define __malloc_debug_set_indent(level) (__malloc_debug_cur_indent = level)
194
195 #else /* !MALLOC_DEBUGGING */
196 # define MALLOC_DEBUG(fmt, args...) (void)0
197 # define MALLOC_DEBUG_INDENT(indent) (void)0
198 #endif /* MALLOC_DEBUGGING */
199
200
201 /* Return SZ rounded down to POWER_OF_2_SIZE (which must be power of 2).  */
202 #define MALLOC_ROUND_DOWN(sz, power_of_2_size)  \
203   ((sz) & ~(power_of_2_size - 1))
204 /* Return SZ rounded to POWER_OF_2_SIZE (which must be power of 2).  */
205 #define MALLOC_ROUND_UP(sz, power_of_2_size)                            \
206   MALLOC_ROUND_DOWN ((sz) + (power_of_2_size - 1), (power_of_2_size))
207
208 /* Return SZ rounded down to a multiple MALLOC_PAGE_SIZE.  */
209 #define MALLOC_ROUND_DOWN_TO_PAGE_SIZE(sz)  \
210   MALLOC_ROUND_DOWN (sz, MALLOC_PAGE_SIZE)
211 /* Return SZ rounded up to a multiple MALLOC_PAGE_SIZE.  */
212 #define MALLOC_ROUND_UP_TO_PAGE_SIZE(sz)  \
213   MALLOC_ROUND_UP (sz, MALLOC_PAGE_SIZE)
214
215
216 /* The malloc heap.  */
217 extern struct heap __malloc_heap;