1: /* Dynamic memory allocation for GNU.
2: Copyright (C) 1985 Richard M. Stallman,
3: based mostly on the public domain work of others.
4:
5: This program is distributed in the hope that it will be useful,
6: but without any warranty. No author or distributor
7: accepts responsibility to anyone for the consequences of using it
8: or for whether it serves any particular purpose or works at all,
9: unless he says so in writing.
10:
11: Permission is granted to anyone to distribute verbatim copies
12: of this program's source code as received, in any medium, provided that
13: the copyright notice, the nonwarraty notice above
14: and this permission notice are preserved,
15: and that the distributor grants the recipient all rights
16: for further redistribution as permitted by this notice,
17: and informs him of these rights.
18:
19: Permission is granted to distribute modified versions of this
20: program's source code, or of portions of it, under the above
21: conditions, plus the conditions that all changed files carry
22: prominent notices stating who last changed them and that the
23: derived material, including anything packaged together with it and
24: conceptually functioning as a modification of it rather than an
25: application of it, is in its entirety subject to a permission
26: notice identical to this one.
27:
28: Permission is granted to distribute this program (verbatim or
29: as modified) in compiled or executable form, provided verbatim
30: redistribution is permitted as stated above for source code, and
31: A. it is accompanied by the corresponding machine-readable
32: source code, under the above conditions, or
33: B. it is accompanied by a written offer, with no time limit,
34: to distribute the corresponding machine-readable source code,
35: under the above conditions, to any one, in return for reimbursement
36: of the cost of distribution. Verbatim redistribution of the
37: written offer must be permitted. Or,
38: C. it is distributed by someone who received only the
39: compiled or executable form, and is accompanied by a copy of the
40: written offer of source code which he received along with it.
41:
42: Permission is granted to distribute this program (verbatim or as modified)
43: in executable form as part of a larger system provided that the source
44: code for this program, including any modifications used,
45: is also distributed or offered as stated in the preceding paragraph.
46:
47: In other words, you are welcome to use, share and improve this program.
48: You are forbidden to forbid anyone else to use, share and improve
49: what you give them. Help stamp out software-hoarding! */
50:
51:
52: /*
53: * @(#)nmalloc.c 1 (Caltech) 2/21/82
54: *
55: * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
56: *
57: * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
58: *
59: * This is a very fast storage allocator. It allocates blocks of a small
60: * number of different sizes, and keeps free lists of each size. Blocks
61: * that don't exactly fit are passed up to the next larger size. In this
62: * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
63: * This is designed for use in a program that uses vast quantities of
64: * memory, but bombs when it runs out. To make it a little better, it
65: * warns the user when he starts to get near the end.
66: *
67: * June 84, ACT: modified rcheck code to check the range given to malloc,
68: * rather than the range determined by the 2-power used.
69: *
70: * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
71: * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
72: * You should call malloc_init to reinitialize after loading dumped Emacs.
73: * Call malloc_stats to get info on memory stats if MSTATS turned on.
74: * realloc knows how to return same block given, just changing its size,
75: * if the power of 2 is correct.
76: */
77:
78: /*
79: * nextf[i] is the pointer to the next free block of size 2^(i+3). The
80: * smallest allocatable block is 8 bytes. The overhead information will
81: * go in the first int of the block, and the returned pointer will point
82: * to the second.
83: *
84: #ifdef MSTATS
85: * nmalloc[i] is the difference between the number of mallocs and frees
86: * for a given block size.
87: #endif /* MSTATS */
88:
89: #ifdef emacs
90: #include "config.h"
91: #endif /* emacs */
92:
93: #include <sys/param.h>
94:
95: /* Determine which kind of system this is. */
96: #include <signal.h>
97: #ifndef SIGTSTP
98: #define USG
99: #else /* SIGTSTP */
100: #ifdef SIGIO
101: #define BSD42
102: #endif /* SIGIO */
103: #endif /* SIGTSTP */
104:
105: #ifndef BSD42
106: #ifndef USG
107: #include <sys/vlimit.h> /* warn the user when near the end */
108: #endif
109: #else /* if BSD42 */
110: #include <sys/time.h>
111: #include <sys/resource.h>
112: #endif /* BSD42 */
113:
114:
115: #if defined (BSD4_1) || defined (USG)
116: #ifdef EXEC_PAGESIZE
117: #define getpagesize() EXEC_PAGESIZE
118: #else
119: #ifdef NBPG
120: #define getpagesize() NBPG * CLSIZE
121: #ifndef CLSIZE
122: #define CLSIZE 1
123: #endif /* no CLSIZE */
124: #else /* no NBPG */
125: #define getpagesize() NBPC
126: #endif /* no NBPG */
127: #endif /* no EXEC_PAGESIZE */
128: #endif /* BSD4_1 or USG */
129:
130:
131: #define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
132: #define ISFREE ((char) 0x54) /* magic byte that implies free block */
133: /* this is for error checking only */
134: #define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
135: memalign, with the rest of the word
136: being the distance to the true
137: beginning of the block. */
138:
139: extern char etext;
140: extern char *start_of_data ();
141:
142: /* These two are for user programs to look at, when they are interested. */
143:
144: int malloc_sbrk_used; /* amount of data space used now */
145: int malloc_sbrk_unused; /* amount more we can have */
146:
147: /* start of data space; can be changed by calling init_malloc */
148: static char *data_space_start;
149:
150: #ifdef MSTATS
151: static int nmalloc[30];
152: static int nmal, nfre;
153: #endif /* MSTATS */
154:
155: /* If range checking is not turned on, all we have is a flag indicating
156: whether memory is allocated, an index in nextf[], and a size field; to
157: realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
158: on whether the former can hold the exact size (given the value of
159: 'index'). If range checking is on, we always need to know how much space
160: is allocated, so the 'size' field is never used. */
161:
162: struct mhead {
163: char mh_alloc; /* ISALLOC or ISFREE */
164: char mh_index; /* index in nextf[] */
165: /* Remainder are valid only when block is allocated */
166: unsigned short mh_size; /* size, if < 0x10000 */
167: #ifdef rcheck
168: unsigned mh_nbytes; /* number of bytes allocated */
169: int mh_magic4; /* should be == MAGIC4 */
170: #endif /* rcheck */
171: };
172:
173: /* Access free-list pointer of a block.
174: It is stored at block + 4.
175: This is not a field in the mhead structure
176: because we want sizeof (struct mhead)
177: to describe the overhead for when the block is in use,
178: and we do not want the free-list pointer to count in that. */
179:
180: #define CHAIN(a) \
181: (*(struct mhead **) (sizeof (char *) + (char *) (a)))
182:
183: #ifdef rcheck
184:
185: /* To implement range checking, we write magic values in at the beginning and
186: end of each allocated block, and make sure they are undisturbed whenever a
187: free or a realloc occurs. */
188: /* Written in each of the 4 bytes following the block's real space */
189: #define MAGIC1 0x55
190: /* Written in the 4 bytes before the block's real space */
191: #define MAGIC4 0x55555555
192: #define ASSERT(p) if (!(p)) botch("p"); else
193: #define 4 /* 4 bytes extra for MAGIC1s */
194: #else
195: #define ASSERT(p)
196: #define EXTRA 0
197: #endif /* rcheck */
198:
199:
200: /* nextf[i] is free list of blocks of size 2**(i + 3) */
201:
202: static struct mhead *nextf[30];
203:
204: /* Number of bytes of writable memory we can expect to be able to get */
205: static int lim_data;
206: /* Level number of warnings already issued.
207: 0 -- no warnings issued.
208: 1 -- 75% warning already issued.
209: 2 -- 85% warning already issued.
210: */
211: static int warnlevel;
212:
213: /* nonzero once initial bunch of free blocks made */
214: static int gotpool;
215:
216: /* Cause reinitialization based on job parameters;
217: also declare where the end of pure storage is. */
218: malloc_init (start)
219: char *start;
220: {
221: data_space_start = start;
222: lim_data = 0;
223: warnlevel = 0;
224: }
225:
226: static
227: morecore (nu) /* ask system for more memory */
228: register int nu; /* size index to get more of */
229: {
230: char *sbrk ();
231: register char *cp;
232: register int nblks;
233: register int siz;
234:
235: if (!data_space_start)
236: {
237: #if defined(USG) && defined (emacs)
238: data_space_start = start_of_data ();
239: #else /* not USG, or not Emacs */
240: data_space_start = &etext;
241: #endif /* not USG, or not Emacs */
242: }
243:
244: if (lim_data == 0)
245: get_lim_data ();
246:
247: /* On initial startup, get two blocks of each size up to 1k bytes */
248: if (!gotpool)
249: getpool (), getpool (), gotpool = 1;
250:
251: /* Find current end of memory and issue warning if getting near max */
252:
253: cp = sbrk (0);
254: siz = cp - data_space_start;
255: malloc_sbrk_used = siz;
256: malloc_sbrk_unused = lim_data - siz;
257:
258: switch (warnlevel)
259: {
260: case 0:
261: if (siz > (lim_data / 4) * 3)
262: {
263: warnlevel++;
264: malloc_warning ("Warning: past 75% of memory limit");
265: }
266: break;
267: case 1:
268: if (siz > (lim_data / 20) * 17)
269: {
270: warnlevel++;
271: malloc_warning ("Warning: past 85% of memory limit");
272: }
273: break;
274: case 2:
275: if (siz > (lim_data / 20) * 19)
276: {
277: warnlevel++;
278: malloc_warning ("Warning: past 95% of memory limit");
279: }
280: break;
281: }
282:
283: if ((int) cp & 0x3ff) /* land on 1K boundaries */
284: sbrk (1024 - ((int) cp & 0x3ff));
285:
286: /* Take at least 2k, and figure out how many blocks of the desired size
287: we're about to get */
288: nblks = 1;
289: if ((siz = nu) < 8)
290: nblks = 1 << ((siz = 8) - nu);
291:
292: if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
293: return; /* no more room! */
294: if ((int) cp & 7)
295: { /* shouldn't happen, but just in case */
296: cp = (char *) (((int) cp + 8) & ~7);
297: nblks--;
298: }
299:
300: /* save new header and link the nblks blocks together */
301: nextf[nu] = (struct mhead *) cp;
302: siz = 1 << (nu + 3);
303: while (1)
304: {
305: ((struct mhead *) cp) -> mh_alloc = ISFREE;
306: ((struct mhead *) cp) -> mh_index = nu;
307: if (--nblks <= 0) break;
308: CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
309: cp += siz;
310: }
311: /* CHAIN ((struct mhead *) cp) = 0; */
312: /* since sbrk() returns cleared core, this is already set */
313: }
314:
315: static
316: getpool ()
317: {
318: register int nu;
319: register char *cp = sbrk (0);
320:
321: if ((int) cp & 0x3ff) /* land on 1K boundaries */
322: sbrk (1024 - ((int) cp & 0x3ff));
323:
324: /* Get 2k of storage */
325:
326: cp = sbrk (04000);
327: if (cp == (char *) -1)
328: return;
329:
330: /* Divide it into an initial 8-word block
331: plus one block of size 2**nu for nu = 3 ... 10. */
332:
333: CHAIN (cp) = nextf[0];
334: nextf[0] = (struct mhead *) cp;
335: ((struct mhead *) cp) -> mh_alloc = ISFREE;
336: ((struct mhead *) cp) -> mh_index = 0;
337: cp += 8;
338:
339: for (nu = 0; nu < 7; nu++)
340: {
341: CHAIN (cp) = nextf[nu];
342: nextf[nu] = (struct mhead *) cp;
343: ((struct mhead *) cp) -> mh_alloc = ISFREE;
344: ((struct mhead *) cp) -> mh_index = nu;
345: cp += 8 << nu;
346: }
347: }
348:
349: char *
350: malloc (n) /* get a block */
351: unsigned n;
352: {
353: register struct mhead *p;
354: register unsigned int nbytes;
355: register int nunits = 0;
356:
357: /* Figure out how many bytes are required, rounding up to the nearest
358: multiple of 4, then figure out which nextf[] area to use */
359: nbytes = (n + sizeof *p + EXTRA + 3) & ~3;
360: {
361: register unsigned int shiftr = (nbytes - 1) >> 2;
362:
363: while (shiftr >>= 1)
364: nunits++;
365: }
366:
367: /* If there are no blocks of the appropriate size, go get some */
368: /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
369: if (nextf[nunits] == 0)
370: morecore (nunits);
371:
372: /* Get one block off the list, and set the new list head */
373: if ((p = nextf[nunits]) == 0)
374: return 0;
375: nextf[nunits] = CHAIN (p);
376:
377: /* Check for free block clobbered */
378: /* If not for this check, we would gobble a clobbered free chain ptr */
379: /* and bomb out on the NEXT allocate of this size block */
380: if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
381: #ifdef rcheck
382: botch ("block on free list clobbered");
383: #else /* not rcheck */
384: abort ();
385: #endif /* not rcheck */
386:
387: /* Fill in the info, and if range checking, set up the magic numbers */
388: p -> mh_alloc = ISALLOC;
389: #ifdef rcheck
390: p -> mh_nbytes = n;
391: p -> mh_magic4 = MAGIC4;
392: {
393: register char *m = (char *) (p + 1) + n;
394:
395: *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
396: }
397: #else /* not rcheck */
398: p -> mh_size = n;
399: #endif /* not rcheck */
400: #ifdef MSTATS
401: nmalloc[nunits]++;
402: nmal++;
403: #endif /* MSTATS */
404: return (char *) (p + 1);
405: }
406:
407: free (mem)
408: char *mem;
409: {
410: register struct mhead *p;
411: {
412: register char *ap = mem;
413:
414: if (ap == 0)
415: return;
416:
417: p = (struct mhead *) ap - 1;
418: if (p -> mh_alloc == ISMEMALIGN)
419: {
420: ap -= p->mh_size;
421: p = (struct mhead *) ap - 1;
422: }
423:
424: if (p -> mh_alloc != ISALLOC)
425: abort ();
426:
427: #ifdef rcheck
428: ASSERT (p -> mh_magic4 == MAGIC4);
429: ap += p -> mh_nbytes;
430: ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
431: ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
432: #endif /* rcheck */
433: }
434: {
435: register int nunits = p -> mh_index;
436:
437: ASSERT (nunits <= 29);
438: p -> mh_alloc = ISFREE;
439: CHAIN (p) = nextf[nunits];
440: nextf[nunits] = p;
441: #ifdef MSTATS
442: nmalloc[nunits]--;
443: nfre++;
444: #endif /* MSTATS */
445: }
446: }
447:
448: char *
449: realloc (mem, n)
450: char *mem;
451: register unsigned n;
452: {
453: register struct mhead *p;
454: register unsigned int tocopy;
455: register int nbytes;
456: register int nunits;
457:
458: if ((p = (struct mhead *) mem) == 0)
459: return malloc (n);
460: p--;
461: nunits = p -> mh_index;
462: ASSERT (p -> mh_alloc == ISALLOC);
463: #ifdef rcheck
464: ASSERT (p -> mh_magic4 == MAGIC4);
465: {
466: register char *m = mem + (tocopy = p -> mh_nbytes);
467: ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
468: ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
469: }
470: #else /* not rcheck */
471: if (p -> mh_index >= 13)
472: tocopy = (1 << (p -> mh_index + 3)) - sizeof *p;
473: else
474: tocopy = p -> mh_size;
475: #endif /* not rcheck */
476:
477: /* See if desired size rounds to same power of 2 as actual size. */
478: nbytes = (n + sizeof *p + EXTRA + 7) & ~7;
479:
480: /* If ok, use the same block, just marking its size as changed. */
481: if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
482: {
483: #ifdef rcheck
484: register char *m = mem + tocopy;
485: *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
486: p-> mh_nbytes = n;
487: m = mem + n;
488: *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
489: #else /* not rcheck */
490: p -> mh_size = n;
491: #endif /* not rcheck */
492: return mem;
493: }
494:
495: if (n < tocopy)
496: tocopy = n;
497: {
498: register char *new;
499:
500: if ((new = malloc (n)) == 0)
501: return 0;
502: bcopy (mem, new, tocopy);
503: free (mem);
504: return new;
505: }
506: }
507:
508: char *
509: memalign (alignment, size)
510: unsigned alignment, size;
511: {
512: register char *ptr = malloc (size + alignment);
513: register char *aligned;
514: register struct mhead *p;
515:
516: if (ptr == 0)
517: return 0;
518: /* If entire block has the desired alignment, just accept it. */
519: if (((int) ptr & (alignment - 1)) == 0)
520: return ptr;
521: /* Otherwise, get address of byte in the block that has that alignment. */
522: aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
523:
524: /* Store a suitable indication of how to free the block,
525: so that free can find the true beginning of it. */
526: p = (struct mhead *) aligned - 1;
527: p -> mh_size = aligned - ptr;
528: p -> mh_alloc = ISMEMALIGN;
529: return aligned;
530: }
531:
532: #ifndef HPUX
533: /* This runs into trouble with getpagesize on HPUX.
534: Patching out seems cleaner than the ugly fix needed. */
535: char *
536: valloc (size)
537: {
538: return memalign (getpagesize (), size);
539: }
540: #endif /* not HPUX */
541:
542: #ifdef MSTATS
543: /* Return statistics describing allocation of blocks of size 2**n. */
544:
545: struct mstats_value
546: {
547: int blocksize;
548: int nfree;
549: int nused;
550: };
551:
552: struct mstats_value
553: malloc_stats (size)
554: int size;
555: {
556: struct mstats_value v;
557: register int i;
558: register struct mhead *p;
559:
560: v.nfree = 0;
561:
562: if (size < 0 || size >= 30)
563: {
564: v.blocksize = 0;
565: v.nused = 0;
566: return v;
567: }
568:
569: v.blocksize = 1 << (size + 3);
570: v.nused = nmalloc[size];
571:
572: for (p = nextf[size]; p; p = CHAIN (p))
573: v.nfree++;
574:
575: return v;
576: }
577: #endif /* MSTATS */
578:
579: /*
580: * This function returns the total number of bytes that the process
581: * will be allowed to allocate via the sbrk(2) system call. On
582: * BSD systems this is the total space allocatable to stack and
583: * data. On USG systems this is the data space only.
584: */
585:
586: #ifdef USG
587:
588: get_lim_data ()
589: {
590: extern long ulimit ();
591:
592: lim_data = ulimit (3, 0);
593: lim_data -= (long) data_space_start;
594: }
595:
596: #else /* not USG */
597: #ifndef BSD42
598:
599: get_lim_data ()
600: {
601: lim_data = vlimit (LIM_DATA, -1);
602: }
603:
604: #else /* BSD42 */
605:
606: get_lim_data ()
607: {
608: struct rlimit XXrlimit;
609:
610: getrlimit (RLIMIT_DATA, &XXrlimit);
611: lim_data = XXrlimit.rlim_cur; /* soft limit */
612: }
613:
614: #endif /* BSD42 */
615: #endif /* not USG */