Mercurial > hg > xemacs-beta
comparison src/malloc.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
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. */ | |
152 #include <signal.h> | |
153 #ifndef SIGTSTP | |
154 #ifndef VMS | |
155 #ifndef USG | |
156 #define USG | |
157 #endif | |
158 #endif /* not VMS */ | |
159 #else /* SIGTSTP */ | |
160 #ifdef SIGIO | |
161 #define BSD4_2 | |
162 #endif /* SIGIO */ | |
163 #endif /* SIGTSTP */ | |
164 | |
165 #if defined(hpux) | |
166 #define USG | |
167 #endif | |
168 | |
169 #endif /* not emacs */ | |
170 | |
171 /* Define getpagesize () if the system does not. */ | |
172 #include "getpagesize.h" | |
173 | |
174 #ifndef BSD4_2 | |
175 #ifndef USG | |
176 #include <sys/vlimit.h> /* warn the user when near the end */ | |
177 #endif /* not USG */ | |
178 #else /* if BSD4_2 */ | |
179 #include <sys/time.h> | |
180 #include <sys/resource.h> | |
181 #endif /* BSD4_2 */ | |
182 | |
183 #ifdef __STDC_ | |
184 #ifndef HPUX | |
185 /* not sure where this for NetBSD should really go | |
186 and it probably applies to other systems */ | |
187 #if !defined(__NetBSD__) && !defined(__bsdi__) | |
188 extern void *sbrk (ptrdiff_t); | |
189 #else | |
190 extern char *sbrk (); | |
191 #endif /* __NetBSD__ */ | |
192 #endif /* HPUX */ | |
193 #else | |
194 extern void *sbrk (); | |
195 #endif /* __STDC__ */ | |
196 | |
197 extern char *start_of_data (); | |
198 | |
199 #ifdef BSD | |
200 #ifndef DATA_SEG_BITS | |
201 #define start_of_data() &etext | |
202 #endif | |
203 #endif | |
204 | |
205 #ifndef emacs | |
206 #define start_of_data() &etext | |
207 #endif | |
208 | |
209 #define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ | |
210 #define ISFREE ((char) 0x54) /* magic byte that implies free block */ | |
211 /* this is for error checking only */ | |
212 #define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by | |
213 memalign, with the rest of the word | |
214 being the distance to the true | |
215 beginning of the block. */ | |
216 | |
217 extern char etext; | |
218 | |
219 /* These two are for user programs to look at, when they are interested. */ | |
220 | |
221 unsigned int malloc_sbrk_used; /* amount of data space used now */ | |
222 unsigned int malloc_sbrk_unused; /* amount more we can have */ | |
223 | |
224 /* start of data space; can be changed by calling init_malloc */ | |
225 static char *data_space_start; | |
226 | |
227 #ifdef MSTATS | |
228 static int nmalloc[30]; | |
229 static int nmal, nfre; | |
230 #endif /* MSTATS */ | |
231 | |
232 /* If range checking is not turned on, all we have is a flag indicating | |
233 whether memory is allocated, an index in nextf[], and a size field; to | |
234 realloc() memory we copy either size bytes or 1<<(index+3) bytes depending | |
235 on whether the former can hold the exact size (given the value of | |
236 'index'). If range checking is on, we always need to know how much space | |
237 is allocated, so the 'size' field is never used. */ | |
238 | |
239 struct mhead { | |
240 char mh_alloc; /* ISALLOC or ISFREE */ | |
241 char mh_index; /* index in nextf[] */ | |
242 /* Remainder are valid only when block is allocated */ | |
243 unsigned short mh_size; /* size, if < 0x10000 */ | |
244 #ifdef rcheck | |
245 unsigned mh_nbytes; /* number of bytes allocated */ | |
246 int mh_magic4; /* should be == MAGIC4 */ | |
247 #endif /* rcheck */ | |
248 }; | |
249 | |
250 /* Access free-list pointer of a block. | |
251 It is stored at block + 4. | |
252 This is not a field in the mhead structure | |
253 because we want sizeof (struct mhead) | |
254 to describe the overhead for when the block is in use, | |
255 and we do not want the free-list pointer to count in that. */ | |
256 | |
257 #define CHAIN(a) \ | |
258 (*(struct mhead **) (sizeof (char *) + (char *) (a))) | |
259 | |
260 #ifdef rcheck | |
261 | |
262 /* To implement range checking, we write magic values in at the beginning and | |
263 end of each allocated block, and make sure they are undisturbed whenever a | |
264 free or a realloc occurs. */ | |
265 /* Written in each of the 4 bytes following the block's real space */ | |
266 #define MAGIC1 0x55 | |
267 /* Written in the 4 bytes before the block's real space */ | |
268 #define MAGIC4 0x55555555 | |
269 #define ASSERT(p) if (!(p)) botch("p"); else | |
270 #define EXTRA 4 /* 4 bytes extra for MAGIC1s */ | |
271 #else | |
272 #define ASSERT(p) | |
273 #define EXTRA 0 | |
274 #endif /* rcheck */ | |
275 | |
276 | |
277 /* nextf[i] is free list of blocks of size 2**(i + 3) */ | |
278 | |
279 static struct mhead *nextf[30]; | |
280 | |
281 /* busy[i] is nonzero while allocation of block size i is in progress. */ | |
282 | |
283 static char busy[30]; | |
284 | |
285 /* Number of bytes of writable memory we can expect to be able to get */ | |
286 extern unsigned int lim_data; | |
287 | |
288 /* Level number of warnings already issued. | |
289 0 -- no warnings issued. | |
290 1 -- 75% warning already issued. | |
291 2 -- 85% warning already issued. | |
292 */ | |
293 static int warnlevel; | |
294 | |
295 /* Function to call to issue a warning; | |
296 0 means don't issue them. */ | |
297 static void (*warnfunction) (); | |
298 | |
299 /* nonzero once initial bunch of free blocks made */ | |
300 static int gotpool; | |
301 | |
302 char *_malloc_base; | |
303 | |
304 static void getpool (); | |
305 | |
306 /* Cause reinitialization based on job parameters; | |
307 also declare where the end of pure storage is. */ | |
308 void | |
309 malloc_init (start, warnfun) | |
310 char *start; | |
311 void (*warnfun) (); | |
312 { | |
313 if (start) | |
314 data_space_start = start; | |
315 lim_data = 0; | |
316 warnlevel = 0; | |
317 warnfunction = warnfun; | |
318 } | |
319 | |
320 /* Return the maximum size to which MEM can be realloc'd | |
321 without actually requiring copying. */ | |
322 | |
323 int | |
324 malloc_usable_size (mem) | |
325 char *mem; | |
326 { | |
327 int blocksize = 8 << (((struct mhead *) mem) - 1) -> mh_index; | |
328 | |
329 return blocksize - sizeof (struct mhead) - EXTRA; | |
330 } | |
331 | |
332 static void get_lim_data (); | |
333 | |
334 static void | |
335 morecore (nu) /* ask system for more memory */ | |
336 int nu; /* size index to get more of */ | |
337 { | |
338 char *cp; | |
339 int nblks; | |
340 unsigned int siz; | |
341 int oldmask; | |
342 | |
343 #ifdef BSD | |
344 #ifndef BSD4_1 | |
345 /* ?? There was a suggestion not to block SIGILL, somehow for GDB's sake. */ | |
346 oldmask = sigsetmask (-1); | |
347 #endif | |
348 #endif | |
349 | |
350 if (!data_space_start) | |
351 { | |
352 data_space_start = start_of_data (); | |
353 } | |
354 | |
355 if (lim_data == 0) | |
356 get_lim_data (); | |
357 | |
358 /* On initial startup, get two blocks of each size up to 1k bytes */ | |
359 if (!gotpool) | |
360 { getpool (); getpool (); gotpool = 1; } | |
361 | |
362 /* Find current end of memory and issue warning if getting near max */ | |
363 | |
364 #ifndef VMS | |
365 /* Maximum virtual memory on VMS is difficult to calculate since it | |
366 * depends on several dynmacially changing things. Also, alignment | |
367 * isn't that important. That is why much of the code here is ifdef'ed | |
368 * out for VMS systems. | |
369 */ | |
370 cp = sbrk (0); | |
371 siz = cp - data_space_start; | |
372 | |
373 if (warnfunction) | |
374 switch (warnlevel) | |
375 { | |
376 case 0: | |
377 if (siz > (lim_data / 4) * 3) | |
378 { | |
379 warnlevel++; | |
380 (*warnfunction) ("Warning: past 75% of memory limit"); | |
381 } | |
382 break; | |
383 case 1: | |
384 if (siz > (lim_data / 20) * 17) | |
385 { | |
386 warnlevel++; | |
387 (*warnfunction) ("Warning: past 85% of memory limit"); | |
388 } | |
389 break; | |
390 case 2: | |
391 if (siz > (lim_data / 20) * 19) | |
392 { | |
393 warnlevel++; | |
394 (*warnfunction) ("Warning: past 95% of memory limit"); | |
395 } | |
396 break; | |
397 } | |
398 | |
399 if ((int) cp & 0x3ff) /* land on 1K boundaries */ | |
400 sbrk (1024 - ((int) cp & 0x3ff)); | |
401 #endif /* not VMS */ | |
402 | |
403 /* Take at least 2k, and figure out how many blocks of the desired size | |
404 we're about to get */ | |
405 nblks = 1; | |
406 if ((siz = nu) < 8) | |
407 nblks = 1 << ((siz = 8) - nu); | |
408 | |
409 if ((cp = sbrk (1 << (siz + 3))) == (char *) -1) | |
410 { | |
411 #ifdef BSD | |
412 #ifndef BSD4_1 | |
413 sigsetmask (oldmask); | |
414 #endif | |
415 #endif | |
416 return; /* no more room! */ | |
417 } | |
418 malloc_sbrk_used = siz; | |
419 malloc_sbrk_unused = lim_data - siz; | |
420 | |
421 #ifndef VMS | |
422 if ((int) cp & 7) | |
423 { /* shouldn't happen, but just in case */ | |
424 cp = (char *) (((int) cp + 8) & ~7); | |
425 nblks--; | |
426 } | |
427 #endif /* not VMS */ | |
428 | |
429 /* save new header and link the nblks blocks together */ | |
430 nextf[nu] = (struct mhead *) cp; | |
431 siz = 1 << (nu + 3); | |
432 while (1) | |
433 { | |
434 ((struct mhead *) cp) -> mh_alloc = ISFREE; | |
435 ((struct mhead *) cp) -> mh_index = nu; | |
436 if (--nblks <= 0) break; | |
437 CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz); | |
438 cp += siz; | |
439 } | |
440 CHAIN ((struct mhead *) cp) = 0; | |
441 | |
442 #ifdef BSD | |
443 #ifndef BSD4_1 | |
444 sigsetmask (oldmask); | |
445 #endif | |
446 #endif | |
447 } | |
448 | |
449 static void | |
450 getpool () | |
451 { | |
452 int nu; | |
453 char *cp = sbrk (0); | |
454 | |
455 if ((int) cp & 0x3ff) /* land on 1K boundaries */ | |
456 sbrk (1024 - ((int) cp & 0x3ff)); | |
457 | |
458 /* Record address of start of space allocated by malloc. */ | |
459 if (_malloc_base == 0) | |
460 _malloc_base = cp; | |
461 | |
462 /* Get 2k of storage */ | |
463 | |
464 cp = sbrk (04000); | |
465 if (cp == (char *) -1) | |
466 return; | |
467 | |
468 /* Divide it into an initial 8-word block | |
469 plus one block of size 2**nu for nu = 3 ... 10. */ | |
470 | |
471 CHAIN (cp) = nextf[0]; | |
472 nextf[0] = (struct mhead *) cp; | |
473 ((struct mhead *) cp) -> mh_alloc = ISFREE; | |
474 ((struct mhead *) cp) -> mh_index = 0; | |
475 cp += 8; | |
476 | |
477 for (nu = 0; nu < 7; nu++) | |
478 { | |
479 CHAIN (cp) = nextf[nu]; | |
480 nextf[nu] = (struct mhead *) cp; | |
481 ((struct mhead *) cp) -> mh_alloc = ISFREE; | |
482 ((struct mhead *) cp) -> mh_index = nu; | |
483 cp += 8 << nu; | |
484 } | |
485 } | |
486 | |
487 char * | |
488 malloc (n) /* get a block */ | |
489 unsigned n; | |
490 { | |
491 struct mhead *p; | |
492 unsigned int nbytes; | |
493 int nunits = 0; | |
494 | |
495 /* Figure out how many bytes are required, rounding up to the nearest | |
496 multiple of 8, then figure out which nestf[] area to use. | |
497 Both the beginning of the header and the beginning of the | |
498 block should be on an eight byte boundary. */ | |
499 nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7; | |
500 { | |
501 unsigned int shiftr = (nbytes - 1) >> 2; | |
502 | |
503 while (shiftr >>= 1) | |
504 nunits++; | |
505 } | |
506 | |
507 /* In case this is reentrant use of malloc from signal handler, | |
508 pick a block size that no other malloc level is currently | |
509 trying to allocate. That's the easiest harmless way not to | |
510 interfere with the other level of execution. */ | |
511 while (busy[nunits]) nunits++; | |
512 busy[nunits] = 1; | |
513 | |
514 /* If there are no blocks of the appropriate size, go get some */ | |
515 /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */ | |
516 if (nextf[nunits] == 0) | |
517 morecore (nunits); | |
518 | |
519 /* Get one block off the list, and set the new list head */ | |
520 if ((p = nextf[nunits]) == 0) | |
521 { | |
522 busy[nunits] = 0; | |
523 return 0; | |
524 } | |
525 nextf[nunits] = CHAIN (p); | |
526 busy[nunits] = 0; | |
527 | |
528 /* Check for free block clobbered */ | |
529 /* If not for this check, we would gobble a clobbered free chain ptr */ | |
530 /* and bomb out on the NEXT allocate of this size block */ | |
531 if (p -> mh_alloc != ISFREE || p -> mh_index != nunits) | |
532 #ifdef rcheck | |
533 botch ("block on free list clobbered"); | |
534 #else /* not rcheck */ | |
535 abort (); | |
536 #endif /* not rcheck */ | |
537 | |
538 /* Fill in the info, and if range checking, set up the magic numbers */ | |
539 p -> mh_alloc = ISALLOC; | |
540 #ifdef rcheck | |
541 p -> mh_nbytes = n; | |
542 p -> mh_magic4 = MAGIC4; | |
543 { | |
544 /* Get the location n after the beginning of the user's space. */ | |
545 char *m = (char *) p + ((sizeof *p + 7) & ~7) + n; | |
546 | |
547 *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1; | |
548 } | |
549 #else /* not rcheck */ | |
550 p -> mh_size = n; | |
551 #endif /* not rcheck */ | |
552 #ifdef MSTATS | |
553 nmalloc[nunits]++; | |
554 nmal++; | |
555 #endif /* MSTATS */ | |
556 return (char *) p + ((sizeof *p + 7) & ~7); | |
557 } | |
558 | |
559 void | |
560 free (mem) | |
561 char *mem; | |
562 { | |
563 struct mhead *p; | |
564 { | |
565 char *ap = mem; | |
566 | |
567 if (ap == 0) | |
568 return; | |
569 | |
570 p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7)); | |
571 if (p -> mh_alloc == ISMEMALIGN) | |
572 { | |
573 ap -= p->mh_size; | |
574 p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7)); | |
575 } | |
576 | |
577 #ifndef rcheck | |
578 if (p -> mh_alloc != ISALLOC) | |
579 abort (); | |
580 | |
581 #else /* rcheck */ | |
582 if (p -> mh_alloc != ISALLOC) | |
583 { | |
584 if (p -> mh_alloc == ISFREE) | |
585 botch ("free: Called with already freed block argument\n"); | |
586 else | |
587 botch ("free: Called with bad argument\n"); | |
588 } | |
589 | |
590 ASSERT (p -> mh_magic4 == MAGIC4); | |
591 ap += p -> mh_nbytes; | |
592 ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1); | |
593 ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1); | |
594 #endif /* rcheck */ | |
595 } | |
596 { | |
597 int nunits = p -> mh_index; | |
598 | |
599 ASSERT (nunits <= 29); | |
600 p -> mh_alloc = ISFREE; | |
601 | |
602 /* Protect against signal handlers calling malloc. */ | |
603 busy[nunits] = 1; | |
604 /* Put this block on the free list. */ | |
605 CHAIN (p) = nextf[nunits]; | |
606 nextf[nunits] = p; | |
607 busy[nunits] = 0; | |
608 | |
609 #ifdef MSTATS | |
610 nmalloc[nunits]--; | |
611 nfre++; | |
612 #endif /* MSTATS */ | |
613 } | |
614 } | |
615 | |
616 char * | |
617 realloc (mem, n) | |
618 char *mem; | |
619 unsigned n; | |
620 { | |
621 struct mhead *p; | |
622 unsigned int tocopy; | |
623 unsigned int nbytes; | |
624 int nunits; | |
625 | |
626 if (mem == 0) | |
627 return malloc (n); | |
628 p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7)); | |
629 nunits = p -> mh_index; | |
630 ASSERT (p -> mh_alloc == ISALLOC); | |
631 #ifdef rcheck | |
632 ASSERT (p -> mh_magic4 == MAGIC4); | |
633 { | |
634 char *m = mem + (tocopy = p -> mh_nbytes); | |
635 ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1); | |
636 ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1); | |
637 } | |
638 #else /* not rcheck */ | |
639 if (p -> mh_index >= 13) | |
640 tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7); | |
641 else | |
642 tocopy = p -> mh_size; | |
643 #endif /* not rcheck */ | |
644 | |
645 /* See if desired size rounds to same power of 2 as actual size. */ | |
646 nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7; | |
647 | |
648 /* If ok, use the same block, just marking its size as changed. */ | |
649 if (nbytes > (4 << nunits) && nbytes <= (8 << nunits)) | |
650 { | |
651 #ifdef rcheck | |
652 char *m = mem + tocopy; | |
653 *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0; | |
654 p-> mh_nbytes = n; | |
655 m = mem + n; | |
656 *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; | |
657 #else /* not rcheck */ | |
658 p -> mh_size = n; | |
659 #endif /* not rcheck */ | |
660 return mem; | |
661 } | |
662 | |
663 if (n < tocopy) | |
664 tocopy = n; | |
665 { | |
666 char *new; | |
667 | |
668 if ((new = malloc (n)) == 0) | |
669 return 0; | |
670 memcpy (new, mem, tocopy); | |
671 free (mem); | |
672 return new; | |
673 } | |
674 } | |
675 | |
676 #ifndef VMS | |
677 | |
678 char * | |
679 memalign (alignment, size) | |
680 unsigned alignment, size; | |
681 { | |
682 char *ptr = malloc (size + alignment); | |
683 char *aligned; | |
684 struct mhead *p; | |
685 | |
686 if (ptr == 0) | |
687 return 0; | |
688 /* If entire block has the desired alignment, just accept it. */ | |
689 if (((int) ptr & (alignment - 1)) == 0) | |
690 return ptr; | |
691 /* Otherwise, get address of byte in the block that has that alignment. */ | |
692 aligned = (char *) (((int) ptr + alignment - 1) & -alignment); | |
693 | |
694 /* Store a suitable indication of how to free the block, | |
695 so that free can find the true beginning of it. */ | |
696 p = (struct mhead *) aligned - 1; | |
697 p -> mh_size = aligned - ptr; | |
698 p -> mh_alloc = ISMEMALIGN; | |
699 return aligned; | |
700 } | |
701 | |
702 #ifndef __hpux | |
703 /* This runs into trouble with getpagesize on HPUX. | |
704 Patching out seems cleaner than the ugly fix needed. */ | |
705 char * | |
706 valloc (size) | |
707 unsigned size; | |
708 { | |
709 return memalign (getpagesize (), size); | |
710 } | |
711 #endif /* not __hpux */ | |
712 #endif /* not VMS */ | |
713 | |
714 #ifdef MSTATS | |
715 /* Return statistics describing allocation of blocks of size 2**n. */ | |
716 | |
717 struct mstats_value | |
718 { | |
719 int blocksize; | |
720 int nfree; | |
721 int nused; | |
722 }; | |
723 | |
724 struct mstats_value | |
725 malloc_stats (size) | |
726 int size; | |
727 { | |
728 struct mstats_value v; | |
729 int i; | |
730 struct mhead *p; | |
731 | |
732 v.nfree = 0; | |
733 | |
734 if (size < 0 || size >= 30) | |
735 { | |
736 v.blocksize = 0; | |
737 v.nused = 0; | |
738 return v; | |
739 } | |
740 | |
741 v.blocksize = 1 << (size + 3); | |
742 v.nused = nmalloc[size]; | |
743 | |
744 for (p = nextf[size]; p; p = CHAIN (p)) | |
745 v.nfree++; | |
746 | |
747 return v; | |
748 } | |
749 int | |
750 malloc_mem_used () | |
751 { | |
752 int i; | |
753 int size_used; | |
754 | |
755 size_used = 0; | |
756 | |
757 for (i = 0; i < 30; i++) | |
758 { | |
759 int allocation_size = 1 << (i + 3); | |
760 struct mhead *p; | |
761 | |
762 size_used += nmalloc[i] * allocation_size; | |
763 } | |
764 | |
765 return size_used; | |
766 } | |
767 | |
768 int | |
769 malloc_mem_free () | |
770 { | |
771 int i; | |
772 int size_unused; | |
773 | |
774 size_unused = 0; | |
775 | |
776 for (i = 0; i < 30; i++) | |
777 { | |
778 int allocation_size = 1 << (i + 3); | |
779 struct mhead *p; | |
780 | |
781 for (p = nextf[i]; p ; p = CHAIN (p)) | |
782 size_unused += allocation_size; | |
783 } | |
784 | |
785 return size_unused; | |
786 } | |
787 #endif /* MSTATS */ | |
788 | |
789 /* | |
790 * This function returns the total number of bytes that the process | |
791 * will be allowed to allocate via the sbrk(2) system call. On | |
792 * BSD systems this is the total space allocatable to stack and | |
793 * data. On USG systems this is the data space only. | |
794 */ | |
795 | |
796 #ifdef USG | |
797 | |
798 static void | |
799 get_lim_data () | |
800 { | |
801 extern long ulimit (); | |
802 | |
803 #ifdef ULIMIT_BREAK_VALUE | |
804 lim_data = ULIMIT_BREAK_VALUE; | |
805 #else | |
806 lim_data = ulimit (3, 0); | |
807 #endif | |
808 | |
809 lim_data -= (long) data_space_start; | |
810 } | |
811 | |
812 #else /* not USG */ | |
813 #ifndef BSD4_2 | |
814 | |
815 static void | |
816 get_lim_data () | |
817 { | |
818 lim_data = vlimit (LIM_DATA, -1); | |
819 } | |
820 | |
821 #else /* BSD4_2 */ | |
822 | |
823 static void | |
824 get_lim_data () | |
825 { | |
826 struct rlimit XXrlimit; | |
827 | |
828 getrlimit (RLIMIT_DATA, &XXrlimit); | |
829 #ifdef RLIM_INFINITY | |
830 lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */ | |
831 #else | |
832 lim_data = XXrlimit.rlim_cur; /* soft limit */ | |
833 #endif | |
834 } | |
835 | |
836 #endif /* BSD4_2 */ | |
837 #endif /* not USG */ | |
838 | |
839 #ifdef VMS | |
840 /* There is a problem when dumping and restoring things on VMS. Calls | |
841 * to SBRK don't necessarily result in contiguous allocation. Dumping | |
842 * doesn't work when it isn't. Therefore, we make the initial | |
843 * allocation contiguous by allocating a big chunk, and do SBRKs from | |
844 * there. Once Emacs has dumped there is no reason to continue | |
845 * contiguous allocation, malloc doesn't depend on it. | |
846 * | |
847 * There is a further problem of using brk and sbrk while using VMS C | |
848 * run time library routines malloc, calloc, etc. The documentation | |
849 * says that this is a no-no, although I'm not sure why this would be | |
850 * a problem. In any case, we remove the necessity to call brk and | |
851 * sbrk, by calling calloc (to assure zero filled data) rather than | |
852 * sbrk. | |
853 * | |
854 * VMS_ALLOCATION_SIZE is the size of the allocation array. This | |
855 * should be larger than the malloc size before dumping. Making this | |
856 * too large will result in the startup procedure slowing down since | |
857 * it will require more space and time to map it in. | |
858 * | |
859 * The value for VMS_ALLOCATION_SIZE in the following define was determined | |
860 * by running emacs linked (and a large allocation) with the debugger and | |
861 * looking to see how much storage was used. The allocation was 201 pages, | |
862 * so I rounded it up to a power of two. | |
863 */ | |
864 #ifndef VMS_ALLOCATION_SIZE | |
865 #define VMS_ALLOCATION_SIZE (512*256) | |
866 #endif | |
867 | |
868 /* Use VMS RTL definitions */ | |
869 #undef sbrk | |
870 #undef brk | |
871 #undef malloc | |
872 int vms_out_initial = 0; | |
873 char vms_initial_buffer[VMS_ALLOCATION_SIZE]; | |
874 static char *vms_current_brk = &vms_initial_buffer; | |
875 static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1]; | |
876 | |
877 #include <stdio.h> | |
878 | |
879 char * | |
880 sys_sbrk (incr) | |
881 int incr; | |
882 { | |
883 char *sbrk(), *temp, *ptr; | |
884 | |
885 if (vms_out_initial) | |
886 { | |
887 /* out of initial allocation... */ | |
888 if (!(temp = malloc (incr))) | |
889 temp = (char *) -1; | |
890 } | |
891 else | |
892 { | |
893 /* otherwise, go out of our area */ | |
894 ptr = vms_current_brk + incr; /* new current_brk */ | |
895 if (ptr <= vms_end_brk) | |
896 { | |
897 temp = vms_current_brk; | |
898 vms_current_brk = ptr; | |
899 } | |
900 else | |
901 { | |
902 vms_out_initial = 1; /* mark as out of initial allocation */ | |
903 if (!(temp = malloc (incr))) | |
904 temp = (char *) -1; | |
905 } | |
906 } | |
907 return temp; | |
908 } | |
909 #endif /* VMS */ |