1:
2:
3: #define _MALLOC_INTERNAL
4: #ifdef HAVE_GTK_AND_PTHREAD
5: #define USE_PTHREAD
6: #endif
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33: #ifndef _MALLOC_H
34:
35: #define _MALLOC_H 1
36:
37: #ifdef _MALLOC_INTERNAL
38:
39: #ifdef HAVE_CONFIG_H
40: #include <config.h>
41: #endif
42:
43: #if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \
44: || defined STDC_HEADERS || defined PROTOTYPES) \
45: && ! defined (BROKEN_PROTOTYPES))
46: #undef PP
47: #define PP(args) args
48: #undef __ptr_t
49: #define __ptr_t void *
50: #else
51: #undef PP
52: #define PP(args) ()
53: #undef __ptr_t
54: #define __ptr_t char *
55: #endif
56:
57: #if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
58: #include <string.h>
59: #else
60: #ifndef memset
61: #define memset(s, zero, n) bzero ((s), (n))
62: #endif
63: #ifndef memcpy
64: #define memcpy(d, s, n) bcopy ((s), (d), (n))
65: #endif
66: #endif
67:
68: #ifdef HAVE_LIMITS_H
69: #include <limits.h>
70: #endif
71: #ifndef CHAR_BIT
72: #define CHAR_BIT 8
73: #endif
74:
75: #ifdef HAVE_UNISTD_H
76: #include <unistd.h>
77: #endif
78:
79: #ifdef USE_PTHREAD
80: #include <pthread.h>
81: #endif
82:
83: #endif
84:
85:
86: #ifdef __cplusplus
87: extern "C"
88: {
89: #endif
90:
91: #ifdef STDC_HEADERS
92: #include <stddef.h>
93: #define __malloc_size_t size_t
94: #define __malloc_ptrdiff_t ptrdiff_t
95: #else
96: #ifdef __GNUC__
97: #include <stddef.h>
98: #ifdef __SIZE_TYPE__
99: #define __malloc_size_t __SIZE_TYPE__
100: #endif
101: #endif
102: #ifndef __malloc_size_t
103: #define __malloc_size_t unsigned int
104: #endif
105: #define __malloc_ptrdiff_t int
106: #endif
107:
108: #ifndef NULL
109: #define NULL 0
110: #endif
111:
112: #ifndef FREE_RETURN_TYPE
113: #define FREE_RETURN_TYPE void
114: #endif
115:
116:
117:
118: extern __ptr_t malloc PP ((__malloc_size_t __size));
119:
120:
121: extern __ptr_t realloc PP ((__ptr_t __ptr, __malloc_size_t __size));
122:
123: extern __ptr_t calloc PP ((__malloc_size_t __nmemb, __malloc_size_t __size));
124:
125: extern FREE_RETURN_TYPE free PP ((__ptr_t __ptr));
126:
127:
128: #if ! (defined (_MALLOC_INTERNAL) && __DJGPP__ - 0 == 1)
129: extern __ptr_t memalign PP ((__malloc_size_t __alignment,
130: __malloc_size_t __size));
131: #endif
132:
133:
134: #if ! (defined (_MALLOC_INTERNAL) && defined (GMALLOC_INHIBIT_VALLOC))
135: extern __ptr_t valloc PP ((__malloc_size_t __size));
136: #endif
137:
138:
139: #ifdef _MALLOC_INTERNAL
140:
141:
142:
143:
144:
145:
146: #define INT_BIT (CHAR_BIT * sizeof(int))
147: #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
148: #define BLOCKSIZE (1 << BLOCKLOG)
149: #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
150:
151:
152:
153: #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
154:
155:
156:
157: #define FINAL_FREE_BLOCKS 8
158:
159:
160: typedef union
161: {
162:
163: struct
164: {
165:
166:
167: int type;
168: union
169: {
170: struct
171: {
172: __malloc_size_t nfree;
173: __malloc_size_t first;
174: } frag;
175:
176:
177:
178: __malloc_ptrdiff_t size;
179: } info;
180: } busy;
181:
182:
183: struct
184: {
185: __malloc_size_t size;
186: __malloc_size_t next;
187: __malloc_size_t prev;
188: } free;
189: } malloc_info;
190:
191:
192: extern char *_heapbase;
193:
194:
195: extern malloc_info *_heapinfo;
196:
197:
198: #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
199: #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase))
200:
201:
202: extern __malloc_size_t _heapindex;
203:
204:
205: extern __malloc_size_t _heaplimit;
206:
207:
208: struct list
209: {
210: struct list *next;
211: struct list *prev;
212: };
213:
214:
215: extern struct list _fraghead[];
216:
217:
218: struct alignlist
219: {
220: struct alignlist *next;
221: __ptr_t aligned;
222: __ptr_t exact;
223: };
224: extern struct alignlist *_aligned_blocks;
225:
226:
227: extern __malloc_size_t _chunks_used;
228: extern __malloc_size_t _bytes_used;
229: extern __malloc_size_t _chunks_free;
230: extern __malloc_size_t _bytes_free;
231:
232:
233:
234:
235: extern __ptr_t _malloc_internal PP ((__malloc_size_t __size));
236: extern __ptr_t _realloc_internal PP ((__ptr_t __ptr, __malloc_size_t __size));
237: extern void _free_internal PP ((__ptr_t __ptr));
238:
239: #ifdef USE_PTHREAD
240: extern pthread_mutex_t _malloc_mutex;
241: #define LOCK() pthread_mutex_lock (&_malloc_mutex)
242: #define UNLOCK() pthread_mutex_unlock (&_malloc_mutex)
243: #else
244: #define LOCK()
245: #define UNLOCK()
246: #endif
247:
248: #endif
249:
250:
251:
252: extern __ptr_t malloc_find_object_address PP ((__ptr_t __ptr));
253:
254:
255:
256: extern __ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size));
257:
258:
259: extern __ptr_t __default_morecore PP ((__malloc_ptrdiff_t __size));
260:
261:
262:
263: extern void (*__after_morecore_hook) PP ((void));
264:
265:
266:
267: extern __malloc_size_t __malloc_extra_blocks;
268:
269:
270: extern int __malloc_initialized;
271:
272: extern int __malloc_initialize PP ((void));
273:
274:
275: extern void (*__malloc_initialize_hook) PP ((void));
276: extern void (*__free_hook) PP ((__ptr_t __ptr));
277: extern __ptr_t (*__malloc_hook) PP ((__malloc_size_t __size));
278: extern __ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size));
279: extern __ptr_t (*__memalign_hook) PP ((__malloc_size_t __size,
280: __malloc_size_t __alignment));
281:
282:
283:
284: enum mcheck_status
285: {
286: MCHECK_DISABLED = -1,
287: MCHECK_OK,
288: MCHECK_FREE,
289: MCHECK_HEAD,
290: MCHECK_TAIL
291: };
292:
293:
294:
295:
296:
297: extern int mcheck PP ((void (*__abortfunc) PP ((enum mcheck_status))));
298:
299:
300:
301:
302: extern enum mcheck_status mprobe PP ((__ptr_t __ptr));
303:
304:
305: extern void mtrace PP ((void));
306: extern void muntrace PP ((void));
307:
308:
309: struct mstats
310: {
311: __malloc_size_t bytes_total;
312: __malloc_size_t chunks_used;
313: __malloc_size_t bytes_used;
314: __malloc_size_t chunks_free;
315: __malloc_size_t bytes_free;
316: };
317:
318:
319: extern struct mstats mstats PP ((void));
320:
321:
322: extern void memory_warnings PP ((__ptr_t __start,
323: void (*__warnfun) PP ((const char *))));
324:
325:
326:
327:
328:
329: extern __ptr_t r_alloc PP ((__ptr_t *__handleptr, __malloc_size_t __size));
330:
331:
332: extern void r_alloc_free PP ((__ptr_t *__handleptr));
333:
334:
335: extern __ptr_t r_re_alloc PP ((__ptr_t *__handleptr, __malloc_size_t __size));
336:
337:
338: #ifdef __cplusplus
339: }
340: #endif
341:
342: #endif
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365: #ifndef _MALLOC_INTERNAL
366: #define _MALLOC_INTERNAL
367: #include <malloc.h>
368: #endif
369: #include <errno.h>
370:
371:
372: #if defined(CYGWIN)
373: extern __ptr_t bss_sbrk PP ((ptrdiff_t __size));
374: extern int bss_sbrk_did_unexec;
375: #endif
376: __ptr_t (*__morecore) PP ((ptrdiff_t __size)) = __default_morecore;
377:
378:
379: __ptr_t (*__malloc_hook) PP ((__malloc_size_t __size));
380:
381:
382: char *_heapbase;
383:
384:
385: malloc_info *_heapinfo;
386:
387:
388: static __malloc_size_t heapsize;
389:
390:
391: __malloc_size_t _heapindex;
392:
393:
394: __malloc_size_t _heaplimit;
395:
396:
397: struct list _fraghead[BLOCKLOG];
398:
399:
400: __malloc_size_t _chunks_used;
401: __malloc_size_t _bytes_used;
402: __malloc_size_t _chunks_free;
403: __malloc_size_t _bytes_free;
404:
405:
406: int __malloc_initialized;
407:
408: __malloc_size_t __malloc_extra_blocks;
409:
410: void (*__malloc_initialize_hook) PP ((void));
411: void (*__after_morecore_hook) PP ((void));
412:
413: #if defined GC_MALLOC_CHECK && defined GC_PROTECT_MALLOC_STATE
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424: #include <sys/types.h>
425: #include <sys/mman.h>
426:
427: static int state_protected_p;
428: static __malloc_size_t last_state_size;
429: static malloc_info *last_heapinfo;
430:
431: void
432: protect_malloc_state (protect_p)
433: int protect_p;
434: {
435:
436:
437: if (_heapinfo != last_heapinfo
438: && last_heapinfo
439: && state_protected_p)
440: mprotect (last_heapinfo, last_state_size, PROT_READ | PROT_WRITE);
441:
442: last_state_size = _heaplimit * sizeof *_heapinfo;
443: last_heapinfo = _heapinfo;
444:
445: if (protect_p != state_protected_p)
446: {
447: state_protected_p = protect_p;
448: if (mprotect (_heapinfo, last_state_size,
449: protect_p ? PROT_READ : PROT_READ | PROT_WRITE) != 0)
450: abort ();
451: }
452: }
453:
454: #define PROTECT_MALLOC_STATE(PROT) protect_malloc_state(PROT)
455:
456: #else
457: #define PROTECT_MALLOC_STATE(PROT)
458: #endif
459:
460:
461:
462: static __ptr_t align PP ((__malloc_size_t));
463: static __ptr_t
464: align (size)
465: __malloc_size_t size;
466: {
467: __ptr_t result;
468: unsigned long int adj;
469:
470:
471:
472:
473:
474: if ((__malloc_ptrdiff_t)size < 0)
475: result = 0;
476: else
477: result = (*__morecore) (size);
478: adj = (unsigned long int) ((unsigned long int) ((char *) result -
479: (char *) NULL)) % BLOCKSIZE;
480: if (adj != 0)
481: {
482: __ptr_t new;
483: adj = BLOCKSIZE - adj;
484: new = (*__morecore) (adj);
485: result = (char *) result + adj;
486: }
487:
488: if (__after_morecore_hook)
489: (*__after_morecore_hook) ();
490:
491: return result;
492: }
493:
494:
495:
496:
497: static __ptr_t get_contiguous_space PP ((__malloc_ptrdiff_t, __ptr_t));
498: static __ptr_t
499: get_contiguous_space (size, position)
500: __malloc_ptrdiff_t size;
501: __ptr_t position;
502: {
503: __ptr_t before;
504: __ptr_t after;
505:
506: before = (*__morecore) (0);
507:
508:
509: if (before != position)
510: return 0;
511:
512:
513: after = (*__morecore) (size);
514: if (!after)
515: return 0;
516:
517:
518: if (after != position)
519: {
520: (*__morecore) (- size);
521: return 0;
522: }
523:
524: return after;
525: }
526:
527:
528:
529:
530:
531: static void register_heapinfo PP ((void));
532: #ifdef __GNUC__
533: __inline__
534: #endif
535: static void
536: register_heapinfo ()
537: {
538: __malloc_size_t block, blocks;
539:
540: block = BLOCK (_heapinfo);
541: blocks = BLOCKIFY (heapsize * sizeof (malloc_info));
542:
543:
544: _bytes_used += blocks * BLOCKSIZE;
545: ++_chunks_used;
546:
547:
548: _heapinfo[block].busy.type = 0;
549: _heapinfo[block].busy.info.size = blocks;
550:
551: while (--blocks > 0)
552: _heapinfo[block + blocks].busy.info.size = -blocks;
553: }
554:
555: #ifdef USE_PTHREAD
556: static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT;
557: pthread_mutex_t _malloc_mutex;
558: #endif
559:
560: static void
561: malloc_initialize_1 ()
562: {
563: #ifdef GC_MCHECK
564: mcheck (NULL);
565: #endif
566:
567: if (__malloc_initialize_hook)
568: (*__malloc_initialize_hook) ();
569:
570: #ifdef USE_PTHREAD
571: {
572: pthread_mutexattr_t attr;
573:
574: pthread_mutexattr_init (&attr);
575: pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
576: pthread_mutex_init (&_malloc_mutex, &attr);
577: pthread_mutexattr_destroy (&attr);
578: }
579: #endif
580:
581: