428
+ − 1 /* dynamic memory allocation for GNU.
+ − 2 Copyright (C) 1985, 1987 Free Software Foundation, Inc.
+ − 3
+ − 4 NO WARRANTY
+ − 5
+ − 6 BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+ − 7 NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
+ − 8 WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
+ − 9 RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
+ − 10 WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ − 11 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ − 12 FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
+ − 13 AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+ − 14 DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+ − 15 CORRECTION.
+ − 16
+ − 17 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+ − 18 STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
+ − 19 WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
+ − 20 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
+ − 21 OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+ − 22 USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
+ − 23 DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
+ − 24 A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
+ − 25 PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ − 26 DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+ − 27
+ − 28 GENERAL PUBLIC LICENSE TO COPY
+ − 29
+ − 30 1. You may copy and distribute verbatim copies of this source file
+ − 31 as you receive it, in any medium, provided that you conspicuously and
+ − 32 appropriately publish on each copy a valid copyright notice "Copyright
+ − 33 (C) 1985 Free Software Foundation, Inc."; and include following the
+ − 34 copyright notice a verbatim copy of the above disclaimer of warranty
+ − 35 and of this License. You may charge a distribution fee for the
+ − 36 physical act of transferring a copy.
+ − 37
+ − 38 2. You may modify your copy or copies of this source file or
+ − 39 any portion of it, and copy and distribute such modifications under
+ − 40 the terms of Paragraph 1 above, provided that you also do the following:
+ − 41
+ − 42 a) cause the modified files to carry prominent notices stating
+ − 43 that you changed the files and the date of any change; and
+ − 44
+ − 45 b) cause the whole of any work that you distribute or publish,
+ − 46 that in whole or in part contains or is a derivative of this
+ − 47 program or any part thereof, to be licensed at no charge to all
+ − 48 third parties on terms identical to those contained in this
+ − 49 License Agreement (except that you may choose to grant more extensive
+ − 50 warranty protection to some or all third parties, at your option).
+ − 51
+ − 52 c) You may charge a distribution fee for the physical act of
+ − 53 transferring a copy, and you may at your option offer warranty
+ − 54 protection in exchange for a fee.
+ − 55
+ − 56 Mere aggregation of another unrelated program with this program (or its
+ − 57 derivative) on a volume of a storage or distribution medium does not bring
+ − 58 the other program under the scope of these terms.
+ − 59
+ − 60 3. You may copy and distribute this program (or a portion or derivative
+ − 61 of it, under Paragraph 2) in object code or executable form under the terms
+ − 62 of Paragraphs 1 and 2 above provided that you also do one of the following:
+ − 63
+ − 64 a) accompany it with the complete corresponding machine-readable
+ − 65 source code, which must be distributed under the terms of
+ − 66 Paragraphs 1 and 2 above; or,
+ − 67
+ − 68 b) accompany it with a written offer, valid for at least three
+ − 69 years, to give any third party free (except for a nominal
+ − 70 shipping charge) a complete machine-readable copy of the
+ − 71 corresponding source code, to be distributed under the terms of
+ − 72 Paragraphs 1 and 2 above; or,
+ − 73
+ − 74 c) accompany it with the information you received as to where the
+ − 75 corresponding source code may be obtained. (This alternative is
+ − 76 allowed only for noncommercial distribution and only if you
+ − 77 received the program in object code or executable form alone.)
+ − 78
+ − 79 For an executable file, complete source code means all the source code for
+ − 80 all modules it contains; but, as a special exception, it need not include
+ − 81 source code for modules which are standard libraries that accompany the
+ − 82 operating system on which the executable file runs.
+ − 83
+ − 84 4. You may not copy, sublicense, distribute or transfer this program
+ − 85 except as expressly provided under this License Agreement. Any attempt
+ − 86 otherwise to copy, sublicense, distribute or transfer this program is void and
+ − 87 your rights to use the program under this License agreement shall be
+ − 88 automatically terminated. However, parties who have received computer
+ − 89 software programs from you with this License Agreement will not have
+ − 90 their licenses terminated so long as such parties remain in full compliance.
+ − 91
+ − 92 5. If you wish to incorporate parts of this program into other free
+ − 93 programs whose distribution conditions are different, write to the
+ − 94 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ − 95 MA 02111-1307, USA.. We have not yet worked out a simple rule that
+ − 96 can be stated here, but we will often permit this. We will be guided
+ − 97 by the two goals of preserving the free status of all derivatives of
+ − 98 our free software and of promoting the sharing and reuse of software.
+ − 99
+ − 100
+ − 101 In other words, you are welcome to use, share and improve this program.
+ − 102 You are forbidden to forbid anyone else to use, share and improve
+ − 103 what you give them. Help stamp out software-hoarding! */
+ − 104
+ − 105 /* Synched up with: Not synched with FSF. */
+ − 106
+ − 107
+ − 108 /*
+ − 109 * @(#)nmalloc.c 1 (Caltech) 2/21/82
+ − 110 *
+ − 111 * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
+ − 112 *
+ − 113 * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
+ − 114 *
+ − 115 * This is a very fast storage allocator. It allocates blocks of a small
+ − 116 * number of different sizes, and keeps free lists of each size. Blocks
+ − 117 * that don't exactly fit are passed up to the next larger size. In this
+ − 118 * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
+ − 119 * This is designed for use in a program that uses vast quantities of
+ − 120 * memory, but bombs when it runs out. To make it a little better, it
+ − 121 * warns the user when he starts to get near the end.
+ − 122 *
+ − 123 * June 84, ACT: modified rcheck code to check the range given to malloc,
+ − 124 * rather than the range determined by the 2-power used.
+ − 125 *
+ − 126 * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
+ − 127 * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
+ − 128 * You should call malloc_init to reinitialize after loading dumped Emacs.
+ − 129 * Call malloc_stats to get info on memory stats if MSTATS turned on.
+ − 130 * realloc knows how to return same block given, just changing its size,
+ − 131 * if the power of 2 is correct.
+ − 132 */
+ − 133
+ − 134 /*
+ − 135 * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ − 136 * smallest allocatable block is 8 bytes. The overhead information will
+ − 137 * go in the first int of the block, and the returned pointer will point
+ − 138 * to the second.
+ − 139 *
+ − 140 #ifdef MSTATS
+ − 141 * nmalloc[i] is the difference between the number of mallocs and frees
+ − 142 * for a given block size.
+ − 143 #endif MSTATS
+ − 144 */
+ − 145
+ − 146 #ifdef emacs
+ − 147 /* config.h specifies which kind of system this is. */
+ − 148 #include <config.h>
+ − 149 #else
+ − 150
+ − 151 /* Determine which kind of system this is. */
978
+ − 152 #include "syssignal.h"
428
+ − 153 #ifndef SIGTSTP
+ − 154 #ifndef USG
+ − 155 #define USG
+ − 156 #endif
+ − 157 #else /* SIGTSTP */
+ − 158 #ifdef SIGIO
+ − 159 #define BSD4_2
+ − 160 #endif /* SIGIO */
+ − 161 #endif /* SIGTSTP */
+ − 162
+ − 163 #if defined(hpux)
+ − 164 #define USG
+ − 165 #endif
+ − 166
+ − 167 #endif /* not emacs */
+ − 168
+ − 169 #include <stddef.h>
+ − 170
+ − 171 /* Define getpagesize () if the system does not. */
+ − 172 #include "getpagesize.h"
+ − 173
+ − 174 #ifdef HAVE_ULIMIT_H
+ − 175 #include <ulimit.h>
+ − 176 #endif
+ − 177
+ − 178 #ifndef BSD4_2
+ − 179 #ifndef USG
+ − 180 #include <sys/vlimit.h> /* warn the user when near the end */
+ − 181 #endif /* not USG */
+ − 182 #else /* if BSD4_2 */
+ − 183 #include <sys/time.h>
+ − 184 #include <sys/resource.h>
+ − 185 #endif /* BSD4_2 */
+ − 186
+ − 187 #ifdef __STDC__
+ − 188 #ifndef HPUX
+ − 189 /* not sure where this for NetBSD should really go
+ − 190 and it probably applies to other systems */
+ − 191 #if !defined(__NetBSD__) && !defined(__bsdi__) && !defined(__OpenBSD__)
+ − 192 extern void *sbrk (ptrdiff_t);
+ − 193 #else
+ − 194 extern char *sbrk ();
+ − 195 #endif /* __NetBSD__ or __OpenBSD__ */
+ − 196 #endif /* HPUX */
+ − 197 #else
+ − 198 extern void *sbrk ();
+ − 199 #endif /* __STDC__ */
+ − 200
+ − 201 extern char *start_of_data (void);
+ − 202
+ − 203 #ifdef BSD
+ − 204 #define start_of_data() &etext
+ − 205 #endif
+ − 206
+ − 207 #ifndef emacs
+ − 208 #define start_of_data() &etext
+ − 209 #endif
+ − 210
+ − 211 #define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
+ − 212 #define ISFREE ((char) 0x54) /* magic byte that implies free block */
+ − 213 /* this is for error checking only */
+ − 214 #define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
+ − 215 memalign, with the rest of the word
+ − 216 being the distance to the true
+ − 217 beginning of the block. */
+ − 218
+ − 219 extern char etext;
+ − 220
+ − 221 /* These two are for user programs to look at, when they are interested. */
+ − 222
665
+ − 223 Bytecount malloc_sbrk_used; /* amount of data space used now */
+ − 224 Bytecount malloc_sbrk_unused; /* amount more we can have */
428
+ − 225
+ − 226 /* start of data space; can be changed by calling init_malloc */
+ − 227 static char *data_space_start;
+ − 228
+ − 229 #ifdef MSTATS
+ − 230 static int nmalloc[30];
+ − 231 static int nmal, nfre;
+ − 232 #endif /* MSTATS */
+ − 233
+ − 234 /* If range checking is not turned on, all we have is a flag indicating
+ − 235 whether memory is allocated, an index in nextf[], and a size field; to
+ − 236 realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
+ − 237 on whether the former can hold the exact size (given the value of
+ − 238 'index'). If range checking is on, we always need to know how much space
+ − 239 is allocated, so the 'size' field is never used. */
+ − 240
+ − 241 struct mhead {
+ − 242 char mh_alloc; /* ISALLOC or ISFREE */
+ − 243 char mh_index; /* index in nextf[] */
+ − 244 /* Remainder are valid only when block is allocated */
+ − 245 unsigned short mh_size; /* size, if < 0x10000 */
+ − 246 #ifdef rcheck
+ − 247 unsigned mh_nbytes; /* number of bytes allocated */
+ − 248 int mh_magic4; /* should be == MAGIC4 */
+ − 249 #endif /* rcheck */
+ − 250 };
+ − 251
+ − 252 /* Access free-list pointer of a block.
+ − 253 It is stored at block + 4.
+ − 254 This is not a field in the mhead structure
+ − 255 because we want sizeof (struct mhead)
+ − 256 to describe the overhead for when the block is in use,
+ − 257 and we do not want the free-list pointer to count in that. */
+ − 258
+ − 259 #define CHAIN(a) \
+ − 260 (*(struct mhead **) (sizeof (char *) + (char *) (a)))
+ − 261
+ − 262 #ifdef rcheck
+ − 263
+ − 264 /* To implement range checking, we write magic values in at the beginning and
+ − 265 end of each allocated block, and make sure they are undisturbed whenever a
+ − 266 free or a realloc occurs. */
+ − 267 /* Written in each of the 4 bytes following the block's real space */
+ − 268 #define MAGIC1 0x55
+ − 269 /* Written in the 4 bytes before the block's real space */
+ − 270 #define MAGIC4 0x55555555
+ − 271 #define ASSERT(p) if (!(p)) botch("p"); else
+ − 272 #define EXTRA 4 /* 4 bytes extra for MAGIC1s */
+ − 273 #else
+ − 274 #define ASSERT(p)
+ − 275 #define EXTRA 0
+ − 276 #endif /* rcheck */
+ − 277
+ − 278
+ − 279 /* nextf[i] is free list of blocks of size 2**(i + 3) */
+ − 280
+ − 281 static struct mhead *nextf[30];
+ − 282
+ − 283 /* busy[i] is nonzero while allocation of block size i is in progress. */
+ − 284
+ − 285 static char busy[30];
+ − 286
+ − 287 /* Number of bytes of writable memory we can expect to be able to get */
2132
+ − 288 extern unsigned long lim_data;
428
+ − 289
+ − 290 /* Level number of warnings already issued.
+ − 291 0 -- no warnings issued.
+ − 292 1 -- 75% warning already issued.
+ − 293 2 -- 85% warning already issued.
+ − 294 */
+ − 295 static int warnlevel;
+ − 296
+ − 297 /* Function to call to issue a warning;
+ − 298 0 means don't issue them. */
+ − 299 static void (*warnfunction) ();
+ − 300
+ − 301 /* nonzero once initial bunch of free blocks made */
+ − 302 static int gotpool;
+ − 303
+ − 304 char *_malloc_base;
+ − 305
+ − 306 static void getpool (void);
+ − 307
+ − 308 /* Cause reinitialization based on job parameters;
+ − 309 also declare where the end of pure storage is. */
+ − 310 void
+ − 311 malloc_init (start, warnfun)
+ − 312 char *start;
+ − 313 void (*warnfun) ();
+ − 314 {
+ − 315 if (start)
+ − 316 data_space_start = start;
+ − 317 lim_data = 0;
+ − 318 warnlevel = 0;
+ − 319 warnfunction = warnfun;
+ − 320 }
+ − 321
+ − 322 /* Return the maximum size to which MEM can be realloc'd
+ − 323 without actually requiring copying. */
+ − 324
+ − 325 int
+ − 326 malloc_usable_size (mem)
+ − 327 char *mem;
+ − 328 {
+ − 329 int blocksize = 8 << (((struct mhead *) mem) - 1) -> mh_index;
+ − 330
+ − 331 return blocksize - sizeof (struct mhead) - EXTRA;
+ − 332 }
+ − 333
+ − 334 static void get_lim_data ();
+ − 335
+ − 336 static void
+ − 337 morecore (nu) /* ask system for more memory */
+ − 338 int nu; /* size index to get more of */
+ − 339 {
+ − 340 char *cp;
+ − 341 int nblks;
2133
+ − 342 unsigned long siz;
428
+ − 343 int oldmask;
+ − 344
+ − 345 #ifdef BSD
+ − 346 #ifndef BSD4_1
+ − 347 /* ?? There was a suggestion not to block SIGILL, somehow for GDB's sake. */
+ − 348 oldmask = sigsetmask (-1);
+ − 349 #endif
+ − 350 #endif
+ − 351
+ − 352 if (!data_space_start)
+ − 353 {
+ − 354 data_space_start = start_of_data ();
+ − 355 }
+ − 356
+ − 357 if (lim_data == 0)
+ − 358 get_lim_data ();
+ − 359
+ − 360 /* On initial startup, get two blocks of each size up to 1k bytes */
+ − 361 if (!gotpool)
+ − 362 { getpool (); getpool (); gotpool = 1; }
+ − 363
+ − 364 /* Find current end of memory and issue warning if getting near max */
+ − 365
+ − 366 cp = sbrk (0);
+ − 367 siz = cp - data_space_start;
+ − 368
+ − 369 if (warnfunction)
+ − 370 switch (warnlevel)
+ − 371 {
+ − 372 case 0:
+ − 373 if (siz > (lim_data / 4) * 3)
+ − 374 {
+ − 375 warnlevel++;
+ − 376 (*warnfunction) ("Warning: past 75% of memory limit");
+ − 377 }
+ − 378 break;
+ − 379 case 1:
+ − 380 if (siz > (lim_data / 20) * 17)
+ − 381 {
+ − 382 warnlevel++;
+ − 383 (*warnfunction) ("Warning: past 85% of memory limit");
+ − 384 }
+ − 385 break;
+ − 386 case 2:
+ − 387 if (siz > (lim_data / 20) * 19)
+ − 388 {
+ − 389 warnlevel++;
+ − 390 (*warnfunction) ("Warning: past 95% of memory limit");
+ − 391 }
+ − 392 break;
+ − 393 }
+ − 394
+ − 395 if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ − 396 sbrk (1024 - ((int) cp & 0x3ff));
+ − 397
+ − 398 /* Take at least 2k, and figure out how many blocks of the desired size
+ − 399 we're about to get */
+ − 400 nblks = 1;
+ − 401 if ((siz = nu) < 8)
+ − 402 nblks = 1 << ((siz = 8) - nu);
+ − 403
+ − 404 if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
+ − 405 {
+ − 406 #ifdef BSD
+ − 407 #ifndef BSD4_1
+ − 408 sigsetmask (oldmask);
+ − 409 #endif
+ − 410 #endif
+ − 411 return; /* no more room! */
+ − 412 }
+ − 413 malloc_sbrk_used = siz;
+ − 414 malloc_sbrk_unused = lim_data - siz;
+ − 415
+ − 416 if ((int) cp & 7)
+ − 417 { /* shouldn't happen, but just in case */
+ − 418 cp = (char *) (((int) cp + 8) & ~7);
+ − 419 nblks--;
+ − 420 }
+ − 421
+ − 422 /* save new header and link the nblks blocks together */
+ − 423 nextf[nu] = (struct mhead *) cp;
+ − 424 siz = 1 << (nu + 3);
+ − 425 while (1)
+ − 426 {
+ − 427 ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ − 428 ((struct mhead *) cp) -> mh_index = nu;
+ − 429 if (--nblks <= 0) break;
+ − 430 CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
+ − 431 cp += siz;
+ − 432 }
+ − 433 CHAIN ((struct mhead *) cp) = 0;
+ − 434
+ − 435 #ifdef BSD
+ − 436 #ifndef BSD4_1
+ − 437 sigsetmask (oldmask);
+ − 438 #endif
+ − 439 #endif
+ − 440 }
+ − 441
+ − 442 static void
+ − 443 getpool (void)
+ − 444 {
+ − 445 int nu;
+ − 446 char *cp = sbrk (0);
+ − 447
+ − 448 if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ − 449 sbrk (1024 - ((int) cp & 0x3ff));
+ − 450
+ − 451 /* Record address of start of space allocated by malloc. */
+ − 452 if (_malloc_base == 0)
+ − 453 _malloc_base = cp;
+ − 454
+ − 455 /* Get 2k of storage */
+ − 456
+ − 457 cp = sbrk (04000);
+ − 458 if (cp == (char *) -1)
+ − 459 return;
+ − 460
+ − 461 /* Divide it into an initial 8-word block
+ − 462 plus one block of size 2**nu for nu = 3 ... 10. */
+ − 463
+ − 464 CHAIN (cp) = nextf[0];
+ − 465 nextf[0] = (struct mhead *) cp;
+ − 466 ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ − 467 ((struct mhead *) cp) -> mh_index = 0;
+ − 468 cp += 8;
+ − 469
+ − 470 for (nu = 0; nu < 7; nu++)
+ − 471 {
+ − 472 CHAIN (cp) = nextf[nu];
+ − 473 nextf[nu] = (struct mhead *) cp;
+ − 474 ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ − 475 ((struct mhead *) cp) -> mh_index = nu;
+ − 476 cp += 8 << nu;
+ − 477 }
+ − 478 }
+ − 479
+ − 480 char *
+ − 481 malloc (n) /* get a block */
+ − 482 unsigned n;
+ − 483 {
+ − 484 struct mhead *p;
+ − 485 unsigned int nbytes;
+ − 486 int nunits = 0;
+ − 487
+ − 488 /* Figure out how many bytes are required, rounding up to the nearest
+ − 489 multiple of 8, then figure out which nestf[] area to use.
+ − 490 Both the beginning of the header and the beginning of the
+ − 491 block should be on an eight byte boundary. */
647
+ − 492 nbytes = (n + ((sizeof (*p) + 7) & ~7) + EXTRA + 7) & ~7;
428
+ − 493 {
+ − 494 unsigned int shiftr = (nbytes - 1) >> 2;
+ − 495
+ − 496 while (shiftr >>= 1)
+ − 497 nunits++;
+ − 498 }
+ − 499
+ − 500 /* In case this is reentrant use of malloc from signal handler,
+ − 501 pick a block size that no other malloc level is currently
+ − 502 trying to allocate. That's the easiest harmless way not to
+ − 503 interfere with the other level of execution. */
+ − 504 while (busy[nunits]) nunits++;
+ − 505 busy[nunits] = 1;
+ − 506
+ − 507 /* If there are no blocks of the appropriate size, go get some */
+ − 508 /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
+ − 509 if (nextf[nunits] == 0)
+ − 510 morecore (nunits);
+ − 511
+ − 512 /* Get one block off the list, and set the new list head */
+ − 513 if ((p = nextf[nunits]) == 0)
+ − 514 {
+ − 515 busy[nunits] = 0;
+ − 516 return 0;
+ − 517 }
+ − 518 nextf[nunits] = CHAIN (p);
+ − 519 busy[nunits] = 0;
+ − 520
+ − 521 /* Check for free block clobbered */
+ − 522 /* If not for this check, we would gobble a clobbered free chain ptr */
+ − 523 /* and bomb out on the NEXT allocate of this size block */
+ − 524 if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
+ − 525 #ifdef rcheck
+ − 526 botch ("block on free list clobbered");
+ − 527 #else /* not rcheck */
2500
+ − 528 ABORT ();
428
+ − 529 #endif /* not rcheck */
+ − 530
+ − 531 /* Fill in the info, and if range checking, set up the magic numbers */
+ − 532 p -> mh_alloc = ISALLOC;
+ − 533 #ifdef rcheck
+ − 534 p -> mh_nbytes = n;
+ − 535 p -> mh_magic4 = MAGIC4;
+ − 536 {
+ − 537 /* Get the location n after the beginning of the user's space. */
647
+ − 538 char *m = (char *) p + ((sizeof (*p) + 7) & ~7) + n;
428
+ − 539
+ − 540 *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
+ − 541 }
+ − 542 #else /* not rcheck */
+ − 543 p -> mh_size = n;
+ − 544 #endif /* not rcheck */
+ − 545 #ifdef MSTATS
+ − 546 nmalloc[nunits]++;
+ − 547 nmal++;
+ − 548 #endif /* MSTATS */
647
+ − 549 return (char *) p + ((sizeof (*p) + 7) & ~7);
428
+ − 550 }
+ − 551
+ − 552 void
+ − 553 free (mem)
+ − 554 char *mem;
+ − 555 {
+ − 556 struct mhead *p;
+ − 557 {
+ − 558 char *ap = mem;
+ − 559
+ − 560 if (ap == 0)
+ − 561 return;
+ − 562
647
+ − 563 p = (struct mhead *) (ap - ((sizeof (*p) + 7) & ~7));
428
+ − 564 if (p -> mh_alloc == ISMEMALIGN)
+ − 565 {
+ − 566 ap -= p->mh_size;
647
+ − 567 p = (struct mhead *) (ap - ((sizeof (*p) + 7) & ~7));
428
+ − 568 }
+ − 569
+ − 570 #ifndef rcheck
+ − 571 if (p -> mh_alloc != ISALLOC)
2500
+ − 572 ABORT ();
428
+ − 573
+ − 574 #else /* rcheck */
+ − 575 if (p -> mh_alloc != ISALLOC)
+ − 576 {
+ − 577 if (p -> mh_alloc == ISFREE)
+ − 578 botch ("free: Called with already freed block argument\n");
+ − 579 else
+ − 580 botch ("free: Called with bad argument\n");
+ − 581 }
+ − 582
+ − 583 ASSERT (p -> mh_magic4 == MAGIC4);
+ − 584 ap += p -> mh_nbytes;
+ − 585 ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
+ − 586 ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
+ − 587 #endif /* rcheck */
+ − 588 }
+ − 589 {
+ − 590 int nunits = p -> mh_index;
+ − 591
+ − 592 ASSERT (nunits <= 29);
+ − 593 p -> mh_alloc = ISFREE;
+ − 594
+ − 595 /* Protect against signal handlers calling malloc. */
+ − 596 busy[nunits] = 1;
+ − 597 /* Put this block on the free list. */
+ − 598 CHAIN (p) = nextf[nunits];
+ − 599 nextf[nunits] = p;
+ − 600 busy[nunits] = 0;
+ − 601
+ − 602 #ifdef MSTATS
+ − 603 nmalloc[nunits]--;
+ − 604 nfre++;
+ − 605 #endif /* MSTATS */
+ − 606 }
+ − 607 }
+ − 608
+ − 609 char *
+ − 610 realloc (mem, n)
+ − 611 char *mem;
+ − 612 unsigned n;
+ − 613 {
+ − 614 struct mhead *p;
+ − 615 unsigned int tocopy;
+ − 616 unsigned int nbytes;
+ − 617 int nunits;
+ − 618
+ − 619 if (mem == 0)
+ − 620 return malloc (n);
647
+ − 621 p = (struct mhead *) (mem - ((sizeof (*p) + 7) & ~7));
428
+ − 622 nunits = p -> mh_index;
+ − 623 ASSERT (p -> mh_alloc == ISALLOC);
+ − 624 #ifdef rcheck
+ − 625 ASSERT (p -> mh_magic4 == MAGIC4);
+ − 626 {
+ − 627 char *m = mem + (tocopy = p -> mh_nbytes);
+ − 628 ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
+ − 629 ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
+ − 630 }
+ − 631 #else /* not rcheck */
+ − 632 if (p -> mh_index >= 13)
647
+ − 633 tocopy = (1 << (p -> mh_index + 3)) - ((sizeof (*p) + 7) & ~7);
428
+ − 634 else
+ − 635 tocopy = p -> mh_size;
+ − 636 #endif /* not rcheck */
+ − 637
+ − 638 /* See if desired size rounds to same power of 2 as actual size. */
647
+ − 639 nbytes = (n + ((sizeof (*p) + 7) & ~7) + EXTRA + 7) & ~7;
428
+ − 640
+ − 641 /* If ok, use the same block, just marking its size as changed. */
+ − 642 if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
+ − 643 {
+ − 644 #ifdef rcheck
+ − 645 char *m = mem + tocopy;
+ − 646 *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
+ − 647 p-> mh_nbytes = n;
+ − 648 m = mem + n;
+ − 649 *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
+ − 650 #else /* not rcheck */
+ − 651 p -> mh_size = n;
+ − 652 #endif /* not rcheck */
+ − 653 return mem;
+ − 654 }
+ − 655
+ − 656 if (n < tocopy)
+ − 657 tocopy = n;
+ − 658 {
3025
+ − 659 char *new_;
428
+ − 660
3025
+ − 661 if ((new_ = malloc (n)) == 0)
428
+ − 662 return 0;
3025
+ − 663 memcpy (new_, mem, tocopy);
428
+ − 664 free (mem);
3025
+ − 665 return new_;
428
+ − 666 }
+ − 667 }
+ − 668
+ − 669
+ − 670 char *
+ − 671 memalign (alignment, size)
+ − 672 unsigned alignment, size;
+ − 673 {
+ − 674 char *ptr = malloc (size + alignment);
+ − 675 char *aligned;
+ − 676 struct mhead *p;
+ − 677
+ − 678 if (ptr == 0)
+ − 679 return 0;
+ − 680 /* If entire block has the desired alignment, just accept it. */
+ − 681 if (((int) ptr & (alignment - 1)) == 0)
+ − 682 return ptr;
+ − 683 /* Otherwise, get address of byte in the block that has that alignment. */
+ − 684 aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
+ − 685
+ − 686 /* Store a suitable indication of how to free the block,
+ − 687 so that free can find the true beginning of it. */
+ − 688 p = (struct mhead *) aligned - 1;
+ − 689 p -> mh_size = aligned - ptr;
+ − 690 p -> mh_alloc = ISMEMALIGN;
+ − 691 return aligned;
+ − 692 }
+ − 693
+ − 694 #ifndef __hpux
+ − 695 /* This runs into trouble with getpagesize on HPUX.
+ − 696 Patching out seems cleaner than the ugly fix needed. */
+ − 697 char *
+ − 698 valloc (size)
+ − 699 unsigned size;
+ − 700 {
+ − 701 return memalign (getpagesize (), size);
+ − 702 }
+ − 703 #endif /* not __hpux */
+ − 704
+ − 705 #ifdef MSTATS
+ − 706 /* Return statistics describing allocation of blocks of size 2**n. */
+ − 707
+ − 708 struct mstats_value
+ − 709 {
+ − 710 int blocksize;
+ − 711 int nfree;
+ − 712 int nused;
+ − 713 };
+ − 714
+ − 715 struct mstats_value
+ − 716 malloc_stats (size)
+ − 717 int size;
+ − 718 {
+ − 719 struct mstats_value v;
+ − 720 int i;
+ − 721 struct mhead *p;
+ − 722
+ − 723 v.nfree = 0;
+ − 724
+ − 725 if (size < 0 || size >= 30)
+ − 726 {
+ − 727 v.blocksize = 0;
+ − 728 v.nused = 0;
+ − 729 return v;
+ − 730 }
+ − 731
+ − 732 v.blocksize = 1 << (size + 3);
+ − 733 v.nused = nmalloc[size];
+ − 734
+ − 735 for (p = nextf[size]; p; p = CHAIN (p))
+ − 736 v.nfree++;
+ − 737
+ − 738 return v;
+ − 739 }
+ − 740 int
442
+ − 741 malloc_mem_used (void)
428
+ − 742 {
+ − 743 int i;
+ − 744 int size_used;
+ − 745
+ − 746 size_used = 0;
+ − 747
+ − 748 for (i = 0; i < 30; i++)
+ − 749 {
+ − 750 int allocation_size = 1 << (i + 3);
+ − 751 struct mhead *p;
+ − 752
+ − 753 size_used += nmalloc[i] * allocation_size;
+ − 754 }
+ − 755
+ − 756 return size_used;
+ − 757 }
+ − 758
+ − 759 int
442
+ − 760 malloc_mem_free (void)
428
+ − 761 {
+ − 762 int i;
+ − 763 int size_unused;
+ − 764
+ − 765 size_unused = 0;
+ − 766
+ − 767 for (i = 0; i < 30; i++)
+ − 768 {
+ − 769 int allocation_size = 1 << (i + 3);
+ − 770 struct mhead *p;
+ − 771
+ − 772 for (p = nextf[i]; p ; p = CHAIN (p))
+ − 773 size_unused += allocation_size;
+ − 774 }
+ − 775
+ − 776 return size_unused;
+ − 777 }
+ − 778 #endif /* MSTATS */
+ − 779
+ − 780 /*
+ − 781 * This function returns the total number of bytes that the process
+ − 782 * will be allowed to allocate via the sbrk(2) system call. On
+ − 783 * BSD systems this is the total space allocatable to stack and
+ − 784 * data. On USG systems this is the data space only.
+ − 785 */
+ − 786
+ − 787 #ifdef USG
+ − 788
+ − 789 static void
442
+ − 790 get_lim_data (void)
428
+ − 791 {
+ − 792 #ifdef ULIMIT_BREAK_VALUE
+ − 793 lim_data = ULIMIT_BREAK_VALUE;
+ − 794 #else
+ − 795 lim_data = ulimit (3, 0);
+ − 796 #endif
+ − 797
+ − 798 lim_data -= (long) data_space_start;
+ − 799 }
+ − 800
+ − 801 #else /* not USG */
+ − 802 #ifndef BSD4_2
+ − 803
+ − 804 static void
442
+ − 805 get_lim_data (void)
428
+ − 806 {
+ − 807 lim_data = vlimit (LIM_DATA, -1);
+ − 808 }
+ − 809
+ − 810 #else /* BSD4_2 */
+ − 811
+ − 812 static void
442
+ − 813 get_lim_data (void)
428
+ − 814 {
+ − 815 struct rlimit XXrlimit;
+ − 816
+ − 817 getrlimit (RLIMIT_DATA, &XXrlimit);
+ − 818 #ifdef RLIM_INFINITY
+ − 819 lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
+ − 820 #else
+ − 821 lim_data = XXrlimit.rlim_cur; /* soft limit */
+ − 822 #endif
+ − 823 }
+ − 824
+ − 825 #endif /* BSD4_2 */
+ − 826 #endif /* not USG */
+ − 827