1 1.1 christos /* $NetBSD: gmalloc.c,v 1.1.1.1 2016/01/13 21:42:18 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */ 4 1.1 christos 5 1.1 christos #define _MALLOC_INTERNAL 6 1.1 christos 7 1.1 christos /* The malloc headers and source files from the C library follow here. */ 8 1.1 christos 9 1.1 christos /* Declarations for `malloc' and friends. 10 1.1 christos Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc. 11 1.1 christos Written May 1989 by Mike Haertel. 12 1.1 christos 13 1.1 christos This library is free software; you can redistribute it and/or 14 1.1 christos modify it under the terms of the GNU Library General Public License as 15 1.1 christos published by the Free Software Foundation; either version 2 of the 16 1.1 christos License, or (at your option) any later version. 17 1.1 christos 18 1.1 christos This library is distributed in the hope that it will be useful, 19 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 20 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 1.1 christos Library General Public License for more details. 22 1.1 christos 23 1.1 christos You should have received a copy of the GNU Library General Public 24 1.1 christos License along with this library; see the file COPYING.LIB. If 25 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 26 1.1 christos Cambridge, MA 02139, USA. 27 1.1 christos 28 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu, 29 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */ 30 1.1 christos 31 1.1 christos #ifndef _MALLOC_H 32 1.1 christos 33 1.1 christos #define _MALLOC_H 1 34 1.1 christos 35 1.1 christos #ifdef _MALLOC_INTERNAL 36 1.1 christos 37 1.1 christos #ifdef HAVE_CONFIG_H 38 1.1 christos #include <config.h> 39 1.1 christos #endif 40 1.1 christos 41 1.1 christos #if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG) 42 1.1 christos #include <string.h> 43 1.1 christos #else 44 1.1 christos #ifndef memset 45 1.1 christos #define memset(s, zero, n) bzero ((s), (n)) 46 1.1 christos #endif 47 1.1 christos #ifndef memcpy 48 1.1 christos #define memcpy(d, s, n) bcopy ((s), (d), (n)) 49 1.1 christos #endif 50 1.1 christos #endif 51 1.1 christos 52 1.1 christos #if defined (__GNU_LIBRARY__) || (defined (__STDC__) && __STDC__) 53 1.1 christos #include <limits.h> 54 1.1 christos #else 55 1.1 christos #ifndef CHAR_BIT 56 1.1 christos #define CHAR_BIT 8 57 1.1 christos #endif 58 1.1 christos #endif 59 1.1 christos 60 1.1 christos #ifdef HAVE_UNISTD_H 61 1.1 christos #include <unistd.h> 62 1.1 christos #endif 63 1.1 christos 64 1.1 christos #endif /* _MALLOC_INTERNAL. */ 65 1.1 christos 66 1.1 christos 67 1.1 christos #ifdef __cplusplus 68 1.1 christos extern "C" 69 1.1 christos { 70 1.1 christos #endif 71 1.1 christos 72 1.1 christos #if defined (__cplusplus) || (defined (__STDC__) && __STDC__) 73 1.1 christos #undef __P 74 1.1 christos #define __P(args) args 75 1.1 christos #undef __ptr_t 76 1.1 christos #define __ptr_t void * 77 1.1 christos #else /* Not C++ or ANSI C. */ 78 1.1 christos #undef __P 79 1.1 christos #define __P(args) () 80 1.1 christos #undef const 81 1.1 christos #define const 82 1.1 christos #undef __ptr_t 83 1.1 christos #define __ptr_t char * 84 1.1 christos #endif /* C++ or ANSI C. */ 85 1.1 christos 86 1.1 christos #if defined (__STDC__) && __STDC__ 87 1.1 christos #include <stddef.h> 88 1.1 christos #define __malloc_size_t size_t 89 1.1 christos #define __malloc_ptrdiff_t ptrdiff_t 90 1.1 christos #else 91 1.1 christos #define __malloc_size_t unsigned int 92 1.1 christos #define __malloc_ptrdiff_t int 93 1.1 christos #endif 94 1.1 christos 95 1.1 christos #ifndef NULL 96 1.1 christos #define NULL 0 97 1.1 christos #endif 98 1.1 christos 99 1.1 christos 100 1.1 christos /* Allocate SIZE bytes of memory. */ 101 1.1 christos extern __ptr_t malloc __P ((__malloc_size_t __size)); 102 1.1 christos /* Re-allocate the previously allocated block 103 1.1 christos in __ptr_t, making the new block SIZE bytes long. */ 104 1.1 christos extern __ptr_t realloc __P ((__ptr_t __ptr, __malloc_size_t __size)); 105 1.1 christos /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ 106 1.1 christos extern __ptr_t calloc __P ((__malloc_size_t __nmemb, __malloc_size_t __size)); 107 1.1 christos /* Free a block allocated by `malloc', `realloc' or `calloc'. */ 108 1.1 christos extern void free __P ((__ptr_t __ptr)); 109 1.1 christos 110 1.1 christos /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ 111 1.1 christos extern __ptr_t memalign __P ((__malloc_size_t __alignment, 112 1.1 christos __malloc_size_t __size)); 113 1.1 christos 114 1.1 christos /* Allocate SIZE bytes on a page boundary. */ 115 1.1 christos extern __ptr_t valloc __P ((__malloc_size_t __size)); 116 1.1 christos 117 1.1 christos 118 1.1 christos #ifdef _MALLOC_INTERNAL 119 1.1 christos 120 1.1 christos /* The allocator divides the heap into blocks of fixed size; large 121 1.1 christos requests receive one or more whole blocks, and small requests 122 1.1 christos receive a fragment of a block. Fragment sizes are powers of two, 123 1.1 christos and all fragments of a block are the same size. When all the 124 1.1 christos fragments in a block have been freed, the block itself is freed. */ 125 1.1 christos #define INT_BIT (CHAR_BIT * sizeof(int)) 126 1.1 christos #define BLOCKLOG (INT_BIT > 16 ? 12 : 9) 127 1.1 christos #define BLOCKSIZE (1 << BLOCKLOG) 128 1.1 christos #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) 129 1.1 christos 130 1.1 christos /* Determine the amount of memory spanned by the initial heap table 131 1.1 christos (not an absolute limit). */ 132 1.1 christos #define HEAP (INT_BIT > 16 ? 4194304 : 65536) 133 1.1 christos 134 1.1 christos /* Number of contiguous free blocks allowed to build up at the end of 135 1.1 christos memory before they will be returned to the system. */ 136 1.1 christos #define FINAL_FREE_BLOCKS 8 137 1.1 christos 138 1.1 christos /* Data structure giving per-block information. */ 139 1.1 christos typedef union 140 1.1 christos { 141 1.1 christos /* Heap information for a busy block. */ 142 1.1 christos struct 143 1.1 christos { 144 1.1 christos /* Zero for a large (multiblock) object, or positive giving the 145 1.1 christos logarithm to the base two of the fragment size. */ 146 1.1 christos int type; 147 1.1 christos union 148 1.1 christos { 149 1.1 christos struct 150 1.1 christos { 151 1.1 christos __malloc_size_t nfree; /* Free frags in a fragmented block. */ 152 1.1 christos __malloc_size_t first; /* First free fragment of the block. */ 153 1.1 christos } frag; 154 1.1 christos /* For a large object, in its first block, this has the number 155 1.1 christos of blocks in the object. In the other blocks, this has a 156 1.1 christos negative number which says how far back the first block is. */ 157 1.1 christos __malloc_ptrdiff_t size; 158 1.1 christos } info; 159 1.1 christos } busy; 160 1.1 christos /* Heap information for a free block 161 1.1 christos (that may be the first of a free cluster). */ 162 1.1 christos struct 163 1.1 christos { 164 1.1 christos __malloc_size_t size; /* Size (in blocks) of a free cluster. */ 165 1.1 christos __malloc_size_t next; /* Index of next free cluster. */ 166 1.1 christos __malloc_size_t prev; /* Index of previous free cluster. */ 167 1.1 christos } free; 168 1.1 christos } malloc_info; 169 1.1 christos 170 1.1 christos /* Pointer to first block of the heap. */ 171 1.1 christos extern char *_heapbase; 172 1.1 christos 173 1.1 christos /* Table indexed by block number giving per-block information. */ 174 1.1 christos extern malloc_info *_heapinfo; 175 1.1 christos 176 1.1 christos /* Address to block number and vice versa. */ 177 1.1 christos #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) 178 1.1 christos #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase)) 179 1.1 christos 180 1.1 christos /* Current search index for the heap table. */ 181 1.1 christos extern __malloc_size_t _heapindex; 182 1.1 christos 183 1.1 christos /* Limit of valid info table indices. */ 184 1.1 christos extern __malloc_size_t _heaplimit; 185 1.1 christos 186 1.1 christos /* Doubly linked lists of free fragments. */ 187 1.1 christos struct list 188 1.1 christos { 189 1.1 christos struct list *next; 190 1.1 christos struct list *prev; 191 1.1 christos }; 192 1.1 christos 193 1.1 christos /* Free list headers for each fragment size. */ 194 1.1 christos extern struct list _fraghead[]; 195 1.1 christos 196 1.1 christos /* List of blocks allocated with `memalign' (or `valloc'). */ 197 1.1 christos struct alignlist 198 1.1 christos { 199 1.1 christos struct alignlist *next; 200 1.1 christos __ptr_t aligned; /* The address that memaligned returned. */ 201 1.1 christos __ptr_t exact; /* The address that malloc returned. */ 202 1.1 christos }; 203 1.1 christos extern struct alignlist *_aligned_blocks; 204 1.1 christos 205 1.1 christos /* Instrumentation. */ 206 1.1 christos extern __malloc_size_t _chunks_used; 207 1.1 christos extern __malloc_size_t _bytes_used; 208 1.1 christos extern __malloc_size_t _chunks_free; 209 1.1 christos extern __malloc_size_t _bytes_free; 210 1.1 christos 211 1.1 christos /* Internal version of `free' used in `morecore' (malloc.c). */ 212 1.1 christos extern void _free_internal __P ((__ptr_t __ptr)); 213 1.1 christos 214 1.1 christos #endif /* _MALLOC_INTERNAL. */ 215 1.1 christos 216 1.1 christos /* Given an address in the middle of a malloc'd object, 217 1.1 christos return the address of the beginning of the object. */ 218 1.1 christos extern __ptr_t malloc_find_object_address __P ((__ptr_t __ptr)); 219 1.1 christos 220 1.1 christos /* Underlying allocation function; successive calls should 221 1.1 christos return contiguous pieces of memory. */ 222 1.1 christos extern __ptr_t (*__morecore) __P ((__malloc_ptrdiff_t __size)); 223 1.1 christos 224 1.1 christos /* Default value of `__morecore'. */ 225 1.1 christos extern __ptr_t __default_morecore __P ((__malloc_ptrdiff_t __size)); 226 1.1 christos 227 1.1 christos /* If not NULL, this function is called after each time 228 1.1 christos `__morecore' is called to increase the data size. */ 229 1.1 christos extern void (*__after_morecore_hook) __P ((void)); 230 1.1 christos 231 1.1 christos /* Nonzero if `malloc' has been called and done its initialization. */ 232 1.1 christos extern int __malloc_initialized; 233 1.1 christos 234 1.1 christos /* Hooks for debugging versions. */ 235 1.1 christos extern void (*__malloc_initialize_hook) __P ((void)); 236 1.1 christos extern void (*__free_hook) __P ((__ptr_t __ptr)); 237 1.1 christos extern __ptr_t (*__malloc_hook) __P ((__malloc_size_t __size)); 238 1.1 christos extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size)); 239 1.1 christos extern __ptr_t (*__memalign_hook) __P ((__malloc_size_t __size, 240 1.1 christos __malloc_size_t __alignment)); 241 1.1 christos 242 1.1 christos /* Return values for `mprobe': these are the kinds of inconsistencies that 243 1.1 christos `mcheck' enables detection of. */ 244 1.1 christos enum mcheck_status 245 1.1 christos { 246 1.1 christos MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */ 247 1.1 christos MCHECK_OK, /* Block is fine. */ 248 1.1 christos MCHECK_FREE, /* Block freed twice. */ 249 1.1 christos MCHECK_HEAD, /* Memory before the block was clobbered. */ 250 1.1 christos MCHECK_TAIL /* Memory after the block was clobbered. */ 251 1.1 christos }; 252 1.1 christos 253 1.1 christos /* Activate a standard collection of debugging hooks. This must be called 254 1.1 christos before `malloc' is ever called. ABORTFUNC is called with an error code 255 1.1 christos (see enum above) when an inconsistency is detected. If ABORTFUNC is 256 1.1 christos null, the standard function prints on stderr and then calls `abort'. */ 257 1.1 christos extern int mcheck __P ((void (*__abortfunc) __P ((enum mcheck_status)))); 258 1.1 christos 259 1.1 christos /* Check for aberrations in a particular malloc'd block. You must have 260 1.1 christos called `mcheck' already. These are the same checks that `mcheck' does 261 1.1 christos when you free or reallocate a block. */ 262 1.1 christos extern enum mcheck_status mprobe __P ((__ptr_t __ptr)); 263 1.1 christos 264 1.1 christos /* Activate a standard collection of tracing hooks. */ 265 1.1 christos extern void mtrace __P ((void)); 266 1.1 christos extern void muntrace __P ((void)); 267 1.1 christos 268 1.1 christos /* Statistics available to the user. */ 269 1.1 christos struct mstats 270 1.1 christos { 271 1.1 christos __malloc_size_t bytes_total; /* Total size of the heap. */ 272 1.1 christos __malloc_size_t chunks_used; /* Chunks allocated by the user. */ 273 1.1 christos __malloc_size_t bytes_used; /* Byte total of user-allocated chunks. */ 274 1.1 christos __malloc_size_t chunks_free; /* Chunks in the free list. */ 275 1.1 christos __malloc_size_t bytes_free; /* Byte total of chunks in the free list. */ 276 1.1 christos }; 277 1.1 christos 278 1.1 christos /* Pick up the current statistics. */ 279 1.1 christos extern struct mstats mstats __P ((void)); 280 1.1 christos 281 1.1 christos /* Call WARNFUN with a warning message when memory usage is high. */ 282 1.1 christos extern void memory_warnings __P ((__ptr_t __start, 283 1.1 christos void (*__warnfun) __P ((const char *)))); 284 1.1 christos 285 1.1 christos 286 1.1 christos /* Relocating allocator. */ 287 1.1 christos 288 1.1 christos /* Allocate SIZE bytes, and store the address in *HANDLEPTR. */ 289 1.1 christos extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, __malloc_size_t __size)); 290 1.1 christos 291 1.1 christos /* Free the storage allocated in HANDLEPTR. */ 292 1.1 christos extern void r_alloc_free __P ((__ptr_t *__handleptr)); 293 1.1 christos 294 1.1 christos /* Adjust the block at HANDLEPTR to be SIZE bytes long. */ 295 1.1 christos extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, __malloc_size_t __size)); 296 1.1 christos 297 1.1 christos 298 1.1 christos #ifdef __cplusplus 299 1.1 christos } 300 1.1 christos #endif 301 1.1 christos 302 1.1 christos #endif /* malloc.h */ 303 1.1 christos /* Allocate memory on a page boundary. 304 1.1 christos Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 305 1.1 christos 306 1.1 christos This library is free software; you can redistribute it and/or 307 1.1 christos modify it under the terms of the GNU Library General Public License as 308 1.1 christos published by the Free Software Foundation; either version 2 of the 309 1.1 christos License, or (at your option) any later version. 310 1.1 christos 311 1.1 christos This library is distributed in the hope that it will be useful, 312 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 313 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 314 1.1 christos Library General Public License for more details. 315 1.1 christos 316 1.1 christos You should have received a copy of the GNU Library General Public 317 1.1 christos License along with this library; see the file COPYING.LIB. If 318 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 319 1.1 christos Cambridge, MA 02139, USA. 320 1.1 christos 321 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu, 322 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */ 323 1.1 christos 324 1.1 christos #if defined (__GNU_LIBRARY__) || defined (_LIBC) 325 1.1 christos #include <stddef.h> 326 1.1 christos #include <sys/cdefs.h> 327 1.1 christos extern size_t __getpagesize __P ((void)); 328 1.1 christos #else 329 1.1 christos #include "getpagesize.h" 330 1.1 christos #define __getpagesize() getpagesize() 331 1.1 christos #endif 332 1.1 christos 333 1.1 christos #ifndef _MALLOC_INTERNAL 334 1.1 christos #define _MALLOC_INTERNAL 335 1.1 christos #include <malloc.h> 336 1.1 christos #endif 337 1.1 christos 338 1.1 christos static __malloc_size_t pagesize; 339 1.1 christos 340 1.1 christos __ptr_t 341 1.1 christos valloc (size) 342 1.1 christos __malloc_size_t size; 343 1.1 christos { 344 1.1 christos if (pagesize == 0) 345 1.1 christos pagesize = __getpagesize (); 346 1.1 christos 347 1.1 christos return memalign (pagesize, size); 348 1.1 christos } 349 1.1 christos /* Memory allocator `malloc'. 350 1.1 christos Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 351 1.1 christos Written May 1989 by Mike Haertel. 352 1.1 christos 353 1.1 christos This library is free software; you can redistribute it and/or 354 1.1 christos modify it under the terms of the GNU Library General Public License as 355 1.1 christos published by the Free Software Foundation; either version 2 of the 356 1.1 christos License, or (at your option) any later version. 357 1.1 christos 358 1.1 christos This library is distributed in the hope that it will be useful, 359 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 360 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 361 1.1 christos Library General Public License for more details. 362 1.1 christos 363 1.1 christos You should have received a copy of the GNU Library General Public 364 1.1 christos License along with this library; see the file COPYING.LIB. If 365 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 366 1.1 christos Cambridge, MA 02139, USA. 367 1.1 christos 368 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu, 369 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */ 370 1.1 christos 371 1.1 christos #ifndef _MALLOC_INTERNAL 372 1.1 christos #define _MALLOC_INTERNAL 373 1.1 christos #include <malloc.h> 374 1.1 christos #endif 375 1.1 christos 376 1.1 christos /* How to really get more memory. */ 377 1.1 christos __ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore; 378 1.1 christos 379 1.1 christos /* Debugging hook for `malloc'. */ 380 1.1 christos __ptr_t (*__malloc_hook) __P ((__malloc_size_t __size)); 381 1.1 christos 382 1.1 christos /* Pointer to the base of the first block. */ 383 1.1 christos char *_heapbase; 384 1.1 christos 385 1.1 christos /* Block information table. Allocated with align/__free (not malloc/free). */ 386 1.1 christos malloc_info *_heapinfo; 387 1.1 christos 388 1.1 christos /* Number of info entries. */ 389 1.1 christos static __malloc_size_t heapsize; 390 1.1 christos 391 1.1 christos /* Search index in the info table. */ 392 1.1 christos __malloc_size_t _heapindex; 393 1.1 christos 394 1.1 christos /* Limit of valid info table indices. */ 395 1.1 christos __malloc_size_t _heaplimit; 396 1.1 christos 397 1.1 christos /* Free lists for each fragment size. */ 398 1.1 christos struct list _fraghead[BLOCKLOG]; 399 1.1 christos 400 1.1 christos /* Instrumentation. */ 401 1.1 christos __malloc_size_t _chunks_used; 402 1.1 christos __malloc_size_t _bytes_used; 403 1.1 christos __malloc_size_t _chunks_free; 404 1.1 christos __malloc_size_t _bytes_free; 405 1.1 christos 406 1.1 christos /* Are you experienced? */ 407 1.1 christos int __malloc_initialized; 408 1.1 christos 409 1.1 christos void (*__malloc_initialize_hook) __P ((void)); 410 1.1 christos void (*__after_morecore_hook) __P ((void)); 411 1.1 christos 412 1.1 christos /* Aligned allocation. */ 413 1.1 christos static __ptr_t align __P ((__malloc_size_t)); 414 1.1 christos static __ptr_t 415 1.1 christos align (size) 416 1.1 christos __malloc_size_t size; 417 1.1 christos { 418 1.1 christos __ptr_t result; 419 1.1 christos unsigned long int adj; 420 1.1 christos 421 1.1 christos result = (*__morecore) (size); 422 1.1 christos adj = (unsigned long int) ((unsigned long int) ((char *) result - 423 1.1 christos (char *) NULL)) % BLOCKSIZE; 424 1.1 christos if (adj != 0) 425 1.1 christos { 426 1.1 christos adj = BLOCKSIZE - adj; 427 1.1 christos (void) (*__morecore) (adj); 428 1.1 christos result = (char *) result + adj; 429 1.1 christos } 430 1.1 christos 431 1.1 christos if (__after_morecore_hook) 432 1.1 christos (*__after_morecore_hook) (); 433 1.1 christos 434 1.1 christos return result; 435 1.1 christos } 436 1.1 christos 437 1.1 christos /* Set everything up and remember that we have. */ 438 1.1 christos static int initialize __P ((void)); 439 1.1 christos static int 440 1.1 christos initialize () 441 1.1 christos { 442 1.1 christos if (__malloc_initialize_hook) 443 1.1 christos (*__malloc_initialize_hook) (); 444 1.1 christos 445 1.1 christos heapsize = HEAP / BLOCKSIZE; 446 1.1 christos _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info)); 447 1.1 christos if (_heapinfo == NULL) 448 1.1 christos return 0; 449 1.1 christos memset (_heapinfo, 0, heapsize * sizeof (malloc_info)); 450 1.1 christos _heapinfo[0].free.size = 0; 451 1.1 christos _heapinfo[0].free.next = _heapinfo[0].free.prev = 0; 452 1.1 christos _heapindex = 0; 453 1.1 christos _heapbase = (char *) _heapinfo; 454 1.1 christos 455 1.1 christos /* Account for the _heapinfo block itself in the statistics. */ 456 1.1 christos _bytes_used = heapsize * sizeof (malloc_info); 457 1.1 christos _chunks_used = 1; 458 1.1 christos 459 1.1 christos __malloc_initialized = 1; 460 1.1 christos return 1; 461 1.1 christos } 462 1.1 christos 463 1.1 christos /* Get neatly aligned memory, initializing or 464 1.1 christos growing the heap info table as necessary. */ 465 1.1 christos static __ptr_t morecore __P ((__malloc_size_t)); 466 1.1 christos static __ptr_t 467 1.1 christos morecore (size) 468 1.1 christos __malloc_size_t size; 469 1.1 christos { 470 1.1 christos __ptr_t result; 471 1.1 christos malloc_info *newinfo, *oldinfo; 472 1.1 christos __malloc_size_t newsize; 473 1.1 christos 474 1.1 christos result = align (size); 475 1.1 christos if (result == NULL) 476 1.1 christos return NULL; 477 1.1 christos 478 1.1 christos /* Check if we need to grow the info table. */ 479 1.1 christos if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) 480 1.1 christos { 481 1.1 christos newsize = heapsize; 482 1.1 christos while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize) 483 1.1 christos newsize *= 2; 484 1.1 christos newinfo = (malloc_info *) align (newsize * sizeof (malloc_info)); 485 1.1 christos if (newinfo == NULL) 486 1.1 christos { 487 1.1 christos (*__morecore) (-size); 488 1.1 christos return NULL; 489 1.1 christos } 490 1.1 christos memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info)); 491 1.1 christos memset (&newinfo[heapsize], 0, 492 1.1 christos (newsize - heapsize) * sizeof (malloc_info)); 493 1.1 christos oldinfo = _heapinfo; 494 1.1 christos newinfo[BLOCK (oldinfo)].busy.type = 0; 495 1.1 christos newinfo[BLOCK (oldinfo)].busy.info.size 496 1.1 christos = BLOCKIFY (heapsize * sizeof (malloc_info)); 497 1.1 christos _heapinfo = newinfo; 498 1.1 christos /* Account for the _heapinfo block itself in the statistics. */ 499 1.1 christos _bytes_used += newsize * sizeof (malloc_info); 500 1.1 christos ++_chunks_used; 501 1.1 christos _free_internal (oldinfo); 502 1.1 christos heapsize = newsize; 503 1.1 christos } 504 1.1 christos 505 1.1 christos _heaplimit = BLOCK ((char *) result + size); 506 1.1 christos return result; 507 1.1 christos } 508 1.1 christos 509 1.1 christos /* Allocate memory from the heap. */ 510 1.1 christos __ptr_t 511 1.1 christos malloc (size) 512 1.1 christos __malloc_size_t size; 513 1.1 christos { 514 1.1 christos __ptr_t result; 515 1.1 christos __malloc_size_t block, blocks, lastblocks, start; 516 1.1 christos register __malloc_size_t i; 517 1.1 christos struct list *next; 518 1.1 christos 519 1.1 christos /* ANSI C allows `malloc (0)' to either return NULL, or to return a 520 1.1 christos valid address you can realloc and free (though not dereference). 521 1.1 christos 522 1.1 christos It turns out that some extant code (sunrpc, at least Ultrix's version) 523 1.1 christos expects `malloc (0)' to return non-NULL and breaks otherwise. 524 1.1 christos Be compatible. */ 525 1.1 christos 526 1.1 christos #if 0 527 1.1 christos if (size == 0) 528 1.1 christos return NULL; 529 1.1 christos #endif 530 1.1 christos 531 1.1 christos if (__malloc_hook != NULL) 532 1.1 christos return (*__malloc_hook) (size); 533 1.1 christos 534 1.1 christos if (!__malloc_initialized) 535 1.1 christos if (!initialize ()) 536 1.1 christos return NULL; 537 1.1 christos 538 1.1 christos if (size < sizeof (struct list)) 539 1.1 christos size = sizeof (struct list); 540 1.1 christos 541 1.1 christos #ifdef SUNOS_LOCALTIME_BUG 542 1.1 christos if (size < 16) 543 1.1 christos size = 16; 544 1.1 christos #endif 545 1.1 christos 546 1.1 christos /* Determine the allocation policy based on the request size. */ 547 1.1 christos if (size <= BLOCKSIZE / 2) 548 1.1 christos { 549 1.1 christos /* Small allocation to receive a fragment of a block. 550 1.1 christos Determine the logarithm to base two of the fragment size. */ 551 1.1 christos register __malloc_size_t log = 1; 552 1.1 christos --size; 553 1.1 christos while ((size /= 2) != 0) 554 1.1 christos ++log; 555 1.1 christos 556 1.1 christos /* Look in the fragment lists for a 557 1.1 christos free fragment of the desired size. */ 558 1.1 christos next = _fraghead[log].next; 559 1.1 christos if (next != NULL) 560 1.1 christos { 561 1.1 christos /* There are free fragments of this size. 562 1.1 christos Pop a fragment out of the fragment list and return it. 563 1.1 christos Update the block's nfree and first counters. */ 564 1.1 christos result = (__ptr_t) next; 565 1.1 christos next->prev->next = next->next; 566 1.1 christos if (next->next != NULL) 567 1.1 christos next->next->prev = next->prev; 568 1.1 christos block = BLOCK (result); 569 1.1 christos if (--_heapinfo[block].busy.info.frag.nfree != 0) 570 1.1 christos _heapinfo[block].busy.info.frag.first = (unsigned long int) 571 1.1 christos ((unsigned long int) ((char *) next->next - (char *) NULL) 572 1.1 christos % BLOCKSIZE) >> log; 573 1.1 christos 574 1.1 christos /* Update the statistics. */ 575 1.1 christos ++_chunks_used; 576 1.1 christos _bytes_used += 1 << log; 577 1.1 christos --_chunks_free; 578 1.1 christos _bytes_free -= 1 << log; 579 1.1 christos } 580 1.1 christos else 581 1.1 christos { 582 1.1 christos /* No free fragments of the desired size, so get a new block 583 1.1 christos and break it into fragments, returning the first. */ 584 1.1 christos result = malloc (BLOCKSIZE); 585 1.1 christos if (result == NULL) 586 1.1 christos return NULL; 587 1.1 christos 588 1.1 christos /* Link all fragments but the first into the free list. */ 589 1.1 christos for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i) 590 1.1 christos { 591 1.1 christos next = (struct list *) ((char *) result + (i << log)); 592 1.1 christos next->next = _fraghead[log].next; 593 1.1 christos next->prev = &_fraghead[log]; 594 1.1 christos next->prev->next = next; 595 1.1 christos if (next->next != NULL) 596 1.1 christos next->next->prev = next; 597 1.1 christos } 598 1.1 christos 599 1.1 christos /* Initialize the nfree and first counters for this block. */ 600 1.1 christos block = BLOCK (result); 601 1.1 christos _heapinfo[block].busy.type = log; 602 1.1 christos _heapinfo[block].busy.info.frag.nfree = i - 1; 603 1.1 christos _heapinfo[block].busy.info.frag.first = i - 1; 604 1.1 christos 605 1.1 christos _chunks_free += (BLOCKSIZE >> log) - 1; 606 1.1 christos _bytes_free += BLOCKSIZE - (1 << log); 607 1.1 christos _bytes_used -= BLOCKSIZE - (1 << log); 608 1.1 christos } 609 1.1 christos } 610 1.1 christos else 611 1.1 christos { 612 1.1 christos /* Large allocation to receive one or more blocks. 613 1.1 christos Search the free list in a circle starting at the last place visited. 614 1.1 christos If we loop completely around without finding a large enough 615 1.1 christos space we will have to get more memory from the system. */ 616 1.1 christos blocks = BLOCKIFY (size); 617 1.1 christos start = block = _heapindex; 618 1.1 christos while (_heapinfo[block].free.size < blocks) 619 1.1 christos { 620 1.1 christos block = _heapinfo[block].free.next; 621 1.1 christos if (block == start) 622 1.1 christos { 623 1.1 christos /* Need to get more from the system. Check to see if 624 1.1 christos the new core will be contiguous with the final free 625 1.1 christos block; if so we don't need to get as much. */ 626 1.1 christos block = _heapinfo[0].free.prev; 627 1.1 christos lastblocks = _heapinfo[block].free.size; 628 1.1 christos if (_heaplimit != 0 && block + lastblocks == _heaplimit && 629 1.1 christos (*__morecore) (0) == ADDRESS (block + lastblocks) && 630 1.1 christos (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL) 631 1.1 christos { 632 1.1 christos /* Which block we are extending (the `final free 633 1.1 christos block' referred to above) might have changed, if 634 1.1 christos it got combined with a freed info table. */ 635 1.1 christos block = _heapinfo[0].free.prev; 636 1.1 christos _heapinfo[block].free.size += (blocks - lastblocks); 637 1.1 christos _bytes_free += (blocks - lastblocks) * BLOCKSIZE; 638 1.1 christos continue; 639 1.1 christos } 640 1.1 christos result = morecore (blocks * BLOCKSIZE); 641 1.1 christos if (result == NULL) 642 1.1 christos return NULL; 643 1.1 christos block = BLOCK (result); 644 1.1 christos _heapinfo[block].busy.type = 0; 645 1.1 christos _heapinfo[block].busy.info.size = blocks; 646 1.1 christos ++_chunks_used; 647 1.1 christos _bytes_used += blocks * BLOCKSIZE; 648 1.1 christos return result; 649 1.1 christos } 650 1.1 christos } 651 1.1 christos 652 1.1 christos /* At this point we have found a suitable free list entry. 653 1.1 christos Figure out how to remove what we need from the list. */ 654 1.1 christos result = ADDRESS (block); 655 1.1 christos if (_heapinfo[block].free.size > blocks) 656 1.1 christos { 657 1.1 christos /* The block we found has a bit left over, 658 1.1 christos so relink the tail end back into the free list. */ 659 1.1 christos _heapinfo[block + blocks].free.size 660 1.1 christos = _heapinfo[block].free.size - blocks; 661 1.1 christos _heapinfo[block + blocks].free.next 662 1.1 christos = _heapinfo[block].free.next; 663 1.1 christos _heapinfo[block + blocks].free.prev 664 1.1 christos = _heapinfo[block].free.prev; 665 1.1 christos _heapinfo[_heapinfo[block].free.prev].free.next 666 1.1 christos = _heapinfo[_heapinfo[block].free.next].free.prev 667 1.1 christos = _heapindex = block + blocks; 668 1.1 christos } 669 1.1 christos else 670 1.1 christos { 671 1.1 christos /* The block exactly matches our requirements, 672 1.1 christos so just remove it from the list. */ 673 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev 674 1.1 christos = _heapinfo[block].free.prev; 675 1.1 christos _heapinfo[_heapinfo[block].free.prev].free.next 676 1.1 christos = _heapindex = _heapinfo[block].free.next; 677 1.1 christos --_chunks_free; 678 1.1 christos } 679 1.1 christos 680 1.1 christos _heapinfo[block].busy.type = 0; 681 1.1 christos _heapinfo[block].busy.info.size = blocks; 682 1.1 christos ++_chunks_used; 683 1.1 christos _bytes_used += blocks * BLOCKSIZE; 684 1.1 christos _bytes_free -= blocks * BLOCKSIZE; 685 1.1 christos 686 1.1 christos /* Mark all the blocks of the object just allocated except for the 687 1.1 christos first with a negative number so you can find the first block by 688 1.1 christos adding that adjustment. */ 689 1.1 christos while (--blocks > 0) 690 1.1 christos _heapinfo[block + blocks].busy.info.size = -blocks; 691 1.1 christos } 692 1.1 christos 693 1.1 christos return result; 694 1.1 christos } 695 1.1 christos 696 1.1 christos #ifndef _LIBC 698 1.1 christos 699 1.1 christos /* On some ANSI C systems, some libc functions call _malloc, _free 700 1.1 christos and _realloc. Make them use the GNU functions. */ 701 1.1 christos 702 1.1 christos __ptr_t 703 1.1 christos _malloc (size) 704 1.1 christos __malloc_size_t size; 705 1.1 christos { 706 1.1 christos return malloc (size); 707 1.1 christos } 708 1.1 christos 709 1.1 christos void 710 1.1 christos _free (ptr) 711 1.1 christos __ptr_t ptr; 712 1.1 christos { 713 1.1 christos free (ptr); 714 1.1 christos } 715 1.1 christos 716 1.1 christos __ptr_t 717 1.1 christos _realloc (ptr, size) 718 1.1 christos __ptr_t ptr; 719 1.1 christos __malloc_size_t size; 720 1.1 christos { 721 1.1 christos return realloc (ptr, size); 722 1.1 christos } 723 1.1 christos 724 1.1 christos #endif 725 1.1 christos /* Free a block of memory allocated by `malloc'. 726 1.1 christos Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc. 727 1.1 christos Written May 1989 by Mike Haertel. 728 1.1 christos 729 1.1 christos This library is free software; you can redistribute it and/or 730 1.1 christos modify it under the terms of the GNU Library General Public License as 731 1.1 christos published by the Free Software Foundation; either version 2 of the 732 1.1 christos License, or (at your option) any later version. 733 1.1 christos 734 1.1 christos This library is distributed in the hope that it will be useful, 735 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 736 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 737 1.1 christos Library General Public License for more details. 738 1.1 christos 739 1.1 christos You should have received a copy of the GNU Library General Public 740 1.1 christos License along with this library; see the file COPYING.LIB. If 741 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 742 1.1 christos Cambridge, MA 02139, USA. 743 1.1 christos 744 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu, 745 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */ 746 1.1 christos 747 1.1 christos #ifndef _MALLOC_INTERNAL 748 1.1 christos #define _MALLOC_INTERNAL 749 1.1 christos #include <malloc.h> 750 1.1 christos #endif 751 1.1 christos 752 1.1 christos /* Debugging hook for free. */ 753 1.1 christos void (*__free_hook) __P ((__ptr_t __ptr)); 754 1.1 christos 755 1.1 christos /* List of blocks allocated by memalign. */ 756 1.1 christos struct alignlist *_aligned_blocks = NULL; 757 1.1 christos 758 1.1 christos /* Return memory to the heap. 759 1.1 christos Like `free' but don't call a __free_hook if there is one. */ 760 1.1 christos void 761 1.1 christos _free_internal (ptr) 762 1.1 christos __ptr_t ptr; 763 1.1 christos { 764 1.1 christos int type; 765 1.1 christos __malloc_size_t block, blocks; 766 1.1 christos register __malloc_size_t i; 767 1.1 christos struct list *prev, *next; 768 1.1 christos 769 1.1 christos block = BLOCK (ptr); 770 1.1 christos 771 1.1 christos type = _heapinfo[block].busy.type; 772 1.1 christos switch (type) 773 1.1 christos { 774 1.1 christos case 0: 775 1.1 christos /* Get as many statistics as early as we can. */ 776 1.1 christos --_chunks_used; 777 1.1 christos _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE; 778 1.1 christos _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE; 779 1.1 christos 780 1.1 christos /* Find the free cluster previous to this one in the free list. 781 1.1 christos Start searching at the last block referenced; this may benefit 782 1.1 christos programs with locality of allocation. */ 783 1.1 christos i = _heapindex; 784 1.1 christos if (i > block) 785 1.1 christos while (i > block) 786 1.1 christos i = _heapinfo[i].free.prev; 787 1.1 christos else 788 1.1 christos { 789 1.1 christos do 790 1.1 christos i = _heapinfo[i].free.next; 791 1.1 christos while (i > 0 && i < block); 792 1.1 christos i = _heapinfo[i].free.prev; 793 1.1 christos } 794 1.1 christos 795 1.1 christos /* Determine how to link this block into the free list. */ 796 1.1 christos if (block == i + _heapinfo[i].free.size) 797 1.1 christos { 798 1.1 christos /* Coalesce this block with its predecessor. */ 799 1.1 christos _heapinfo[i].free.size += _heapinfo[block].busy.info.size; 800 1.1 christos block = i; 801 1.1 christos } 802 1.1 christos else 803 1.1 christos { 804 1.1 christos /* Really link this block back into the free list. */ 805 1.1 christos _heapinfo[block].free.size = _heapinfo[block].busy.info.size; 806 1.1 christos _heapinfo[block].free.next = _heapinfo[i].free.next; 807 1.1 christos _heapinfo[block].free.prev = i; 808 1.1 christos _heapinfo[i].free.next = block; 809 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev = block; 810 1.1 christos ++_chunks_free; 811 1.1 christos } 812 1.1 christos 813 1.1 christos /* Now that the block is linked in, see if we can coalesce it 814 1.1 christos with its successor (by deleting its successor from the list 815 1.1 christos and adding in its size). */ 816 1.1 christos if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) 817 1.1 christos { 818 1.1 christos _heapinfo[block].free.size 819 1.1 christos += _heapinfo[_heapinfo[block].free.next].free.size; 820 1.1 christos _heapinfo[block].free.next 821 1.1 christos = _heapinfo[_heapinfo[block].free.next].free.next; 822 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev = block; 823 1.1 christos --_chunks_free; 824 1.1 christos } 825 1.1 christos 826 1.1 christos /* Now see if we can return stuff to the system. */ 827 1.1 christos blocks = _heapinfo[block].free.size; 828 1.1 christos if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit 829 1.1 christos && (*__morecore) (0) == ADDRESS (block + blocks)) 830 1.1 christos { 831 1.1 christos register __malloc_size_t bytes = blocks * BLOCKSIZE; 832 1.1 christos _heaplimit -= blocks; 833 1.1 christos (*__morecore) (-bytes); 834 1.1 christos _heapinfo[_heapinfo[block].free.prev].free.next 835 1.1 christos = _heapinfo[block].free.next; 836 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev 837 1.1 christos = _heapinfo[block].free.prev; 838 1.1 christos block = _heapinfo[block].free.prev; 839 1.1 christos --_chunks_free; 840 1.1 christos _bytes_free -= bytes; 841 1.1 christos } 842 1.1 christos 843 1.1 christos /* Set the next search to begin at this block. */ 844 1.1 christos _heapindex = block; 845 1.1 christos break; 846 1.1 christos 847 1.1 christos default: 848 1.1 christos /* Do some of the statistics. */ 849 1.1 christos --_chunks_used; 850 1.1 christos _bytes_used -= 1 << type; 851 1.1 christos ++_chunks_free; 852 1.1 christos _bytes_free += 1 << type; 853 1.1 christos 854 1.1 christos /* Get the address of the first free fragment in this block. */ 855 1.1 christos prev = (struct list *) ((char *) ADDRESS (block) + 856 1.1 christos (_heapinfo[block].busy.info.frag.first << type)); 857 1.1 christos 858 1.1 christos if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1) 859 1.1 christos { 860 1.1 christos /* If all fragments of this block are free, remove them 861 1.1 christos from the fragment list and free the whole block. */ 862 1.1 christos next = prev; 863 1.1 christos for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i) 864 1.1 christos next = next->next; 865 1.1 christos prev->prev->next = next; 866 1.1 christos if (next != NULL) 867 1.1 christos next->prev = prev->prev; 868 1.1 christos _heapinfo[block].busy.type = 0; 869 1.1 christos _heapinfo[block].busy.info.size = 1; 870 1.1 christos 871 1.1 christos /* Keep the statistics accurate. */ 872 1.1 christos ++_chunks_used; 873 1.1 christos _bytes_used += BLOCKSIZE; 874 1.1 christos _chunks_free -= BLOCKSIZE >> type; 875 1.1 christos _bytes_free -= BLOCKSIZE; 876 1.1 christos 877 1.1 christos free (ADDRESS (block)); 878 1.1 christos } 879 1.1 christos else if (_heapinfo[block].busy.info.frag.nfree != 0) 880 1.1 christos { 881 1.1 christos /* If some fragments of this block are free, link this 882 1.1 christos fragment into the fragment list after the first free 883 1.1 christos fragment of this block. */ 884 1.1 christos next = (struct list *) ptr; 885 1.1 christos next->next = prev->next; 886 1.1 christos next->prev = prev; 887 1.1 christos prev->next = next; 888 1.1 christos if (next->next != NULL) 889 1.1 christos next->next->prev = next; 890 1.1 christos ++_heapinfo[block].busy.info.frag.nfree; 891 1.1 christos } 892 1.1 christos else 893 1.1 christos { 894 1.1 christos /* No fragments of this block are free, so link this 895 1.1 christos fragment into the fragment list and announce that 896 1.1 christos it is the first free fragment of this block. */ 897 1.1 christos prev = (struct list *) ptr; 898 1.1 christos _heapinfo[block].busy.info.frag.nfree = 1; 899 1.1 christos _heapinfo[block].busy.info.frag.first = (unsigned long int) 900 1.1 christos ((unsigned long int) ((char *) ptr - (char *) NULL) 901 1.1 christos % BLOCKSIZE >> type); 902 1.1 christos prev->next = _fraghead[type].next; 903 1.1 christos prev->prev = &_fraghead[type]; 904 1.1 christos prev->prev->next = prev; 905 1.1 christos if (prev->next != NULL) 906 1.1 christos prev->next->prev = prev; 907 1.1 christos } 908 1.1 christos break; 909 1.1 christos } 910 1.1 christos } 911 1.1 christos 912 1.1 christos /* Return memory to the heap. */ 913 1.1 christos void 914 1.1 christos free (ptr) 915 1.1 christos __ptr_t ptr; 916 1.1 christos { 917 1.1 christos register struct alignlist *l; 918 1.1 christos 919 1.1 christos if (ptr == NULL) 920 1.1 christos return; 921 1.1 christos 922 1.1 christos for (l = _aligned_blocks; l != NULL; l = l->next) 923 1.1 christos if (l->aligned == ptr) 924 1.1 christos { 925 1.1 christos l->aligned = NULL; /* Mark the slot in the list as free. */ 926 1.1 christos ptr = l->exact; 927 1.1 christos break; 928 1.1 christos } 929 1.1 christos 930 1.1 christos if (__free_hook != NULL) 931 1.1 christos (*__free_hook) (ptr); 932 1.1 christos else 933 1.1 christos _free_internal (ptr); 934 1.1 christos } 935 1.1 christos /* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. 936 1.1 christos This file is part of the GNU C Library. 937 1.1 christos 938 1.1 christos The GNU C Library is free software; you can redistribute it and/or 939 1.1 christos modify it under the terms of the GNU Library General Public License as 940 1.1 christos published by the Free Software Foundation; either version 2 of the 941 1.1 christos License, or (at your option) any later version. 942 1.1 christos 943 1.1 christos The GNU C Library is distributed in the hope that it will be useful, 944 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 945 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 946 1.1 christos Library General Public License for more details. 947 1.1 christos 948 1.1 christos You should have received a copy of the GNU Library General Public 949 1.1 christos License along with the GNU C Library; see the file COPYING.LIB. If 950 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 951 1.1 christos Cambridge, MA 02139, USA. */ 952 1.1 christos 953 1.1 christos #ifndef _MALLOC_INTERNAL 954 1.1 christos #define _MALLOC_INTERNAL 955 1.1 christos #include <malloc.h> 956 1.1 christos #endif 957 1.1 christos 958 1.1 christos #ifdef _LIBC 959 1.1 christos 960 1.1 christos #include <ansidecl.h> 961 1.1 christos #include <gnu-stabs.h> 962 1.1 christos 963 1.1 christos #undef cfree 964 1.1 christos 965 1.1 christos function_alias(cfree, free, void, (ptr), 966 1.1 christos DEFUN(cfree, (ptr), PTR ptr)) 967 1.1 christos 968 1.1 christos #else 969 1.1 christos 970 1.1 christos void 971 1.1 christos cfree (ptr) 972 1.1 christos __ptr_t ptr; 973 1.1 christos { 974 1.1 christos free (ptr); 975 1.1 christos } 976 1.1 christos 977 1.1 christos #endif 978 1.1 christos /* Change the size of a block allocated by `malloc'. 979 1.1 christos Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 980 1.1 christos Written May 1989 by Mike Haertel. 981 1.1 christos 982 1.1 christos This library is free software; you can redistribute it and/or 983 1.1 christos modify it under the terms of the GNU Library General Public License as 984 1.1 christos published by the Free Software Foundation; either version 2 of the 985 1.1 christos License, or (at your option) any later version. 986 1.1 christos 987 1.1 christos This library is distributed in the hope that it will be useful, 988 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 989 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 990 1.1 christos Library General Public License for more details. 991 1.1 christos 992 1.1 christos You should have received a copy of the GNU Library General Public 993 1.1 christos License along with this library; see the file COPYING.LIB. If 994 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 995 1.1 christos Cambridge, MA 02139, USA. 996 1.1 christos 997 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu, 998 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */ 999 1.1 christos 1000 1.1 christos #ifndef _MALLOC_INTERNAL 1001 1.1 christos #define _MALLOC_INTERNAL 1002 1.1 christos #include <malloc.h> 1003 1.1 christos #endif 1004 1.1 christos 1005 1.1 christos #if (defined (MEMMOVE_MISSING) || \ 1006 1.1 christos !defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG)) 1007 1.1 christos 1008 1.1 christos /* Snarfed directly from Emacs src/dispnew.c: 1009 1.1 christos XXX Should use system bcopy if it handles overlap. */ 1010 1.1 christos #ifndef emacs 1011 1.1 christos 1012 1.1 christos /* Like bcopy except never gets confused by overlap. */ 1013 1.1 christos 1014 1.1 christos static void 1015 1.1 christos safe_bcopy (from, to, size) 1016 1.1 christos char *from, *to; 1017 1.1 christos int size; 1018 1.1 christos { 1019 1.1 christos if (size <= 0 || from == to) 1020 1.1 christos return; 1021 1.1 christos 1022 1.1 christos /* If the source and destination don't overlap, then bcopy can 1023 1.1 christos handle it. If they do overlap, but the destination is lower in 1024 1.1 christos memory than the source, we'll assume bcopy can handle that. */ 1025 1.1 christos if (to < from || from + size <= to) 1026 1.1 christos bcopy (from, to, size); 1027 1.1 christos 1028 1.1 christos /* Otherwise, we'll copy from the end. */ 1029 1.1 christos else 1030 1.1 christos { 1031 1.1 christos register char *endf = from + size; 1032 1.1 christos register char *endt = to + size; 1033 1.1 christos 1034 1.1 christos /* If TO - FROM is large, then we should break the copy into 1035 1.1 christos nonoverlapping chunks of TO - FROM bytes each. However, if 1036 1.1 christos TO - FROM is small, then the bcopy function call overhead 1037 1.1 christos makes this not worth it. The crossover point could be about 1038 1.1 christos anywhere. Since I don't think the obvious copy loop is too 1039 1.1 christos bad, I'm trying to err in its favor. */ 1040 1.1 christos if (to - from < 64) 1041 1.1 christos { 1042 1.1 christos do 1043 1.1 christos *--endt = *--endf; 1044 1.1 christos while (endf != from); 1045 1.1 christos } 1046 1.1 christos else 1047 1.1 christos { 1048 1.1 christos for (;;) 1049 1.1 christos { 1050 1.1 christos endt -= (to - from); 1051 1.1 christos endf -= (to - from); 1052 1.1 christos 1053 1.1 christos if (endt < to) 1054 1.1 christos break; 1055 1.1 christos 1056 1.1 christos bcopy (endf, endt, to - from); 1057 1.1 christos } 1058 1.1 christos 1059 1.1 christos /* If SIZE wasn't a multiple of TO - FROM, there will be a 1060 1.1 christos little left over. The amount left over is 1061 1.1 christos (endt + (to - from)) - to, which is endt - from. */ 1062 1.1 christos bcopy (from, to, endt - from); 1063 1.1 christos } 1064 1.1 christos } 1065 1.1 christos } 1066 1.1 christos #endif /* Not emacs. */ 1067 1.1 christos 1068 1.1 christos #define memmove(to, from, size) safe_bcopy ((from), (to), (size)) 1069 1.1 christos 1070 1.1 christos #endif 1071 1.1 christos 1072 1.1 christos 1073 1.1 christos #define min(A, B) ((A) < (B) ? (A) : (B)) 1074 1.1 christos 1075 1.1 christos /* Debugging hook for realloc. */ 1076 1.1 christos __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size)); 1077 1.1 christos 1078 1.1 christos /* Resize the given region to the new size, returning a pointer 1079 1.1 christos to the (possibly moved) region. This is optimized for speed; 1080 1.1 christos some benchmarks seem to indicate that greater compactness is 1081 1.1 christos achieved by unconditionally allocating and copying to a 1082 1.1 christos new region. This module has incestuous knowledge of the 1083 1.1 christos internals of both free and malloc. */ 1084 1.1 christos __ptr_t 1085 1.1 christos realloc (ptr, size) 1086 1.1 christos __ptr_t ptr; 1087 1.1 christos __malloc_size_t size; 1088 1.1 christos { 1089 1.1 christos __ptr_t result; 1090 1.1 christos int type; 1091 1.1 christos __malloc_size_t block, blocks, oldlimit; 1092 1.1 christos 1093 1.1 christos if (size == 0) 1094 1.1 christos { 1095 1.1 christos free (ptr); 1096 1.1 christos return malloc (0); 1097 1.1 christos } 1098 1.1 christos else if (ptr == NULL) 1099 1.1 christos return malloc (size); 1100 1.1 christos 1101 1.1 christos if (__realloc_hook != NULL) 1102 1.1 christos return (*__realloc_hook) (ptr, size); 1103 1.1 christos 1104 1.1 christos block = BLOCK (ptr); 1105 1.1 christos 1106 1.1 christos type = _heapinfo[block].busy.type; 1107 1.1 christos switch (type) 1108 1.1 christos { 1109 1.1 christos case 0: 1110 1.1 christos /* Maybe reallocate a large block to a small fragment. */ 1111 1.1 christos if (size <= BLOCKSIZE / 2) 1112 1.1 christos { 1113 1.1 christos result = malloc (size); 1114 1.1 christos if (result != NULL) 1115 1.1 christos { 1116 1.1 christos memcpy (result, ptr, size); 1117 1.1 christos _free_internal (ptr); 1118 1.1 christos return result; 1119 1.1 christos } 1120 1.1 christos } 1121 1.1 christos 1122 1.1 christos /* The new size is a large allocation as well; 1123 1.1 christos see if we can hold it in place. */ 1124 1.1 christos blocks = BLOCKIFY (size); 1125 1.1 christos if (blocks < _heapinfo[block].busy.info.size) 1126 1.1 christos { 1127 1.1 christos /* The new size is smaller; return 1128 1.1 christos excess memory to the free list. */ 1129 1.1 christos _heapinfo[block + blocks].busy.type = 0; 1130 1.1 christos _heapinfo[block + blocks].busy.info.size 1131 1.1 christos = _heapinfo[block].busy.info.size - blocks; 1132 1.1 christos _heapinfo[block].busy.info.size = blocks; 1133 1.1 christos /* We have just created a new chunk by splitting a chunk in two. 1134 1.1 christos Now we will free this chunk; increment the statistics counter 1135 1.1 christos so it doesn't become wrong when _free_internal decrements it. */ 1136 1.1 christos ++_chunks_used; 1137 1.1 christos _free_internal (ADDRESS (block + blocks)); 1138 1.1 christos result = ptr; 1139 1.1 christos } 1140 1.1 christos else if (blocks == _heapinfo[block].busy.info.size) 1141 1.1 christos /* No size change necessary. */ 1142 1.1 christos result = ptr; 1143 1.1 christos else 1144 1.1 christos { 1145 1.1 christos /* Won't fit, so allocate a new region that will. 1146 1.1 christos Free the old region first in case there is sufficient 1147 1.1 christos adjacent free space to grow without moving. */ 1148 1.1 christos blocks = _heapinfo[block].busy.info.size; 1149 1.1 christos /* Prevent free from actually returning memory to the system. */ 1150 1.1 christos oldlimit = _heaplimit; 1151 1.1 christos _heaplimit = 0; 1152 1.1 christos _free_internal (ptr); 1153 1.1 christos _heaplimit = oldlimit; 1154 1.1 christos result = malloc (size); 1155 1.1 christos if (result == NULL) 1156 1.1 christos { 1157 1.1 christos /* Now we're really in trouble. We have to unfree 1158 1.1 christos the thing we just freed. Unfortunately it might 1159 1.1 christos have been coalesced with its neighbors. */ 1160 1.1 christos if (_heapindex == block) 1161 1.1 christos (void) malloc (blocks * BLOCKSIZE); 1162 1.1 christos else 1163 1.1 christos { 1164 1.1 christos __ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE); 1165 1.1 christos (void) malloc (blocks * BLOCKSIZE); 1166 1.1 christos _free_internal (previous); 1167 1.1 christos } 1168 1.1 christos return NULL; 1169 1.1 christos } 1170 1.1 christos if (ptr != result) 1171 1.1 christos memmove (result, ptr, blocks * BLOCKSIZE); 1172 1.1 christos } 1173 1.1 christos break; 1174 1.1 christos 1175 1.1 christos default: 1176 1.1 christos /* Old size is a fragment; type is logarithm 1177 1.1 christos to base two of the fragment size. */ 1178 1.1 christos if (size > (__malloc_size_t) (1 << (type - 1)) && 1179 1.1 christos size <= (__malloc_size_t) (1 << type)) 1180 1.1 christos /* The new size is the same kind of fragment. */ 1181 1.1 christos result = ptr; 1182 1.1 christos else 1183 1.1 christos { 1184 1.1 christos /* The new size is different; allocate a new space, 1185 1.1 christos and copy the lesser of the new size and the old. */ 1186 1.1 christos result = malloc (size); 1187 1.1 christos if (result == NULL) 1188 1.1 christos return NULL; 1189 1.1 christos memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); 1190 1.1 christos free (ptr); 1191 1.1 christos } 1192 1.1 christos break; 1193 1.1 christos } 1194 1.1 christos 1195 1.1 christos return result; 1196 1.1 christos } 1197 1.1 christos /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. 1198 1.1 christos 1199 1.1 christos This library is free software; you can redistribute it and/or 1200 1.1 christos modify it under the terms of the GNU Library General Public License as 1201 1.1 christos published by the Free Software Foundation; either version 2 of the 1202 1.1 christos License, or (at your option) any later version. 1203 1.1 christos 1204 1.1 christos This library is distributed in the hope that it will be useful, 1205 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 1206 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1207 1.1 christos Library General Public License for more details. 1208 1.1 christos 1209 1.1 christos You should have received a copy of the GNU Library General Public 1210 1.1 christos License along with this library; see the file COPYING.LIB. If 1211 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 1212 1.1 christos Cambridge, MA 02139, USA. 1213 1.1 christos 1214 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu, 1215 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */ 1216 1.1 christos 1217 1.1 christos #ifndef _MALLOC_INTERNAL 1218 1.1 christos #define _MALLOC_INTERNAL 1219 1.1 christos #include <malloc.h> 1220 1.1 christos #endif 1221 1.1 christos 1222 1.1 christos /* Allocate an array of NMEMB elements each SIZE bytes long. 1223 1.1 christos The entire array is initialized to zeros. */ 1224 1.1 christos __ptr_t 1225 1.1 christos calloc (nmemb, size) 1226 1.1 christos register __malloc_size_t nmemb; 1227 1.1 christos register __malloc_size_t size; 1228 1.1 christos { 1229 1.1 christos register __ptr_t result = malloc (nmemb * size); 1230 1.1 christos 1231 1.1 christos if (result != NULL) 1232 1.1 christos (void) memset (result, 0, nmemb * size); 1233 1.1 christos 1234 1.1 christos return result; 1235 1.1 christos } 1236 1.1 christos /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 1237 1.1 christos This file is part of the GNU C Library. 1238 1.1 christos 1239 1.1 christos The GNU C Library is free software; you can redistribute it and/or modify 1240 1.1 christos it under the terms of the GNU General Public License as published by 1241 1.1 christos the Free Software Foundation; either version 2, or (at your option) 1242 1.1 christos any later version. 1243 1.1 christos 1244 1.1 christos The GNU C Library is distributed in the hope that it will be useful, 1245 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 1246 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1247 1.1 christos GNU General Public License for more details. 1248 1.1 christos 1249 1.1 christos You should have received a copy of the GNU General Public License 1250 1.1 christos along with the GNU C Library; see the file COPYING. If not, write to 1251 1.1 christos the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 1252 1.1 christos 1253 1.1 christos #ifndef _MALLOC_INTERNAL 1254 1.1 christos #define _MALLOC_INTERNAL 1255 1.1 christos #include <malloc.h> 1256 1.1 christos #endif 1257 1.1 christos 1258 1.1 christos #ifndef __GNU_LIBRARY__ 1259 1.1 christos #define __sbrk sbrk 1260 1.1 christos #endif 1261 1.1 christos 1262 1.1 christos #ifdef __GNU_LIBRARY__ 1263 1.1 christos /* It is best not to declare this and cast its result on foreign operating 1264 1.1 christos systems with potentially hostile include files. */ 1265 1.1 christos extern __ptr_t __sbrk __P ((int increment)); 1266 1.1 christos #endif 1267 1.1 christos 1268 1.1 christos #ifndef NULL 1269 1.1 christos #define NULL 0 1270 1.1 christos #endif 1271 1.1 christos 1272 1.1 christos /* Allocate INCREMENT more bytes of data space, 1273 1.1 christos and return the start of data space, or NULL on errors. 1274 1.1 christos If INCREMENT is negative, shrink data space. */ 1275 1.1 christos __ptr_t 1276 1.1 christos __default_morecore (increment) 1277 1.1 christos #ifdef __STDC__ 1278 1.1 christos ptrdiff_t increment; 1279 1.1 christos #else 1280 1.1 christos int increment; 1281 1.1 christos #endif 1282 1.1 christos { 1283 1.1 christos __ptr_t result = (__ptr_t) __sbrk ((int) increment); 1284 1.1 christos if (result == (__ptr_t) -1) 1285 1.1 christos return NULL; 1286 1.1 christos return result; 1287 1.1 christos } 1288 1.1 christos /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 1289 1.1 christos 1290 1.1 christos This library is free software; you can redistribute it and/or 1291 1.1 christos modify it under the terms of the GNU Library General Public License as 1292 1.1 christos published by the Free Software Foundation; either version 2 of the 1293 1.1 christos License, or (at your option) any later version. 1294 1.1 christos 1295 1.1 christos This library is distributed in the hope that it will be useful, 1296 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 1297 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1298 1.1 christos Library General Public License for more details. 1299 1.1 christos 1300 1.1 christos You should have received a copy of the GNU Library General Public 1301 1.1 christos License along with this library; see the file COPYING.LIB. If 1302 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave, 1303 1.1 christos Cambridge, MA 02139, USA. */ 1304 1.1 christos 1305 1.1 christos #ifndef _MALLOC_INTERNAL 1306 1.1 christos #define _MALLOC_INTERNAL 1307 1.1 christos #include <malloc.h> 1308 1.1 christos #endif 1309 1.1 christos 1310 1.1 christos __ptr_t (*__memalign_hook) __P ((size_t __size, size_t __alignment)); 1311 1.1 christos 1312 1.1 christos __ptr_t 1313 1.1 christos memalign (alignment, size) 1314 1.1 christos __malloc_size_t alignment; 1315 1.1 christos __malloc_size_t size; 1316 1.1 christos { 1317 1.1 christos __ptr_t result; 1318 1.1 christos unsigned long int adj; 1319 1.1 christos 1320 1.1 christos if (__memalign_hook) 1321 1.1 christos return (*__memalign_hook) (alignment, size); 1322 1.1 christos 1323 1.1 christos size = ((size + alignment - 1) / alignment) * alignment; 1324 1.1 christos 1325 1.1 christos result = malloc (size); 1326 1.1 christos if (result == NULL) 1327 1.1 christos return NULL; 1328 1.1 christos adj = (unsigned long int) ((unsigned long int) ((char *) result - 1329 1.1 christos (char *) NULL)) % alignment; 1330 1.1 christos if (adj != 0) 1331 1.1 christos { 1332 1.1 christos struct alignlist *l; 1333 1.1 christos for (l = _aligned_blocks; l != NULL; l = l->next) 1334 1.1 christos if (l->aligned == NULL) 1335 1.1 christos /* This slot is free. Use it. */ 1336 1.1 christos break; 1337 1.1 christos if (l == NULL) 1338 1.1 christos { 1339 1.1 christos l = (struct alignlist *) malloc (sizeof (struct alignlist)); 1340 1.1 christos if (l == NULL) 1341 1.1 christos { 1342 1.1 christos free (result); 1343 1.1 christos return NULL; 1344 1.1 christos } 1345 1.1 christos l->next = _aligned_blocks; 1346 1.1 christos _aligned_blocks = l; 1347 1.1 christos } 1348 1.1 christos l->exact = result; 1349 1.1 christos result = l->aligned = (char *) result + alignment - adj; 1350 1.1 christos } 1351 1.1 christos 1352 1.1 christos return result; 1353 } 1354