Mercurial > emacs
comparison src/ralloc.c @ 1390:92df75f4167f
(check_memory_limits): Reduce warnlevel when usage drops far enough.
(memory_warnings): New function; just set warning data.
Use start_of_data if start is 0.
[!emacs]: Don't include config.h or lisp.h;
instead, use stddef.h. Define POINTER, SIZE, EXCEEDS_LISP_PTR.
[!emacs] (safe_bcopy): Define as macro using memmove.
(r_alloc_free): Clear *ptr.
(r_alloc_init): Renamed from malloc_init. Take no args.
Make it static; declare at top of file.
(r_alloc): Call r_alloc_init, if not initialized yet.
(r_alloc_initialized): Renamed from malloc_initialized; moved to top.
(ROUNDUP): Subtract 1, in case arg is already aligned.
(check_memory_limits): EXCEEDS_LISP_PTR renamed from EXCEEDS_ELISP_PTR.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 11 Oct 1992 20:37:32 +0000 |
parents | 761b9b4fd3ed |
children | 70d0cd4c5bff |
comparison
equal
deleted
inserted
replaced
1389:517c3893ec5b | 1390:92df75f4167f |
---|---|
21 | 21 |
22 Only relocate the blocs neccessary for SIZE in r_alloc_sbrk, | 22 Only relocate the blocs neccessary for SIZE in r_alloc_sbrk, |
23 rather than all of them. This means allowing for a possible | 23 rather than all of them. This means allowing for a possible |
24 hole between the first bloc and the end of malloc storage. */ | 24 hole between the first bloc and the end of malloc storage. */ |
25 | 25 |
26 #ifdef emacs | |
26 #include "config.h" | 27 #include "config.h" |
27 #include "lisp.h" /* Needed for VALBITS. */ | 28 #include "lisp.h" /* Needed for VALBITS. */ |
29 | |
30 /* Declared in dispnew.c, this version doesn't screw up if regions | |
31 overlap. */ | |
32 extern void safe_bcopy (); | |
33 #endif | |
34 | |
35 #ifndef emacs | |
36 #include <stddef.h> | |
37 typedef size_t SIZE; | |
38 typedef void *POINTER; | |
39 #define EXCEEDS_LISP_PTR(x) 0 | |
40 | |
41 #define safe_bcopy(x, y, z) memmove (y, x, z) | |
42 #endif | |
43 | |
28 #undef NULL | 44 #undef NULL |
29 #include "mem_limits.h" | 45 #include "mem_limits.h" |
30 #include "getpagesize.h" | 46 #include "getpagesize.h" |
31 | 47 |
32 #define NIL ((POINTER) 0) | 48 #define NIL ((POINTER) 0) |
33 | 49 |
50 /* A flag to indicate whether we have initialized ralloc yet. For | |
51 Emacs's sake, please do not make this local to malloc_init; on some | |
52 machines, the dumping procedure makes all static variables | |
53 read-only. On these machines, the word static is #defined to be | |
54 the empty string, meaning that r_alloc_initialized becomes an | |
55 automatic variable, and loses its value each time Emacs is started up. */ | |
56 static int r_alloc_initialized = 0; | |
57 | |
58 static void r_alloc_init (); | |
34 | 59 |
35 /* Declarations for working with the malloc, ralloc, and system breaks. */ | 60 /* Declarations for working with the malloc, ralloc, and system breaks. */ |
36 | 61 |
37 /* System call to set the break value. */ | 62 /* System call to set the break value. */ |
38 extern POINTER sbrk (); | 63 extern POINTER sbrk (); |
48 | 73 |
49 /* Macros for rounding. Note that rounding to any value is possible | 74 /* Macros for rounding. Note that rounding to any value is possible |
50 by changing the definition of PAGE. */ | 75 by changing the definition of PAGE. */ |
51 #define PAGE (getpagesize ()) | 76 #define PAGE (getpagesize ()) |
52 #define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0) | 77 #define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0) |
53 #define ROUNDUP(size) (((unsigned int) (size) + PAGE) & ~(PAGE - 1)) | 78 #define ROUNDUP(size) (((unsigned int) (size) + PAGE - 1) & ~(PAGE - 1)) |
54 #define ROUND_TO_PAGE(addr) (addr & (~(PAGE - 1))) | 79 #define ROUND_TO_PAGE(addr) (addr & (~(PAGE - 1))) |
55 | 80 |
56 /* Managing "almost out of memory" warnings. */ | 81 /* Managing "almost out of memory" warnings. */ |
57 | 82 |
58 /* Level of warnings issued. */ | 83 /* Level of warnings issued. */ |
65 static void | 90 static void |
66 check_memory_limits (address) | 91 check_memory_limits (address) |
67 POINTER address; | 92 POINTER address; |
68 { | 93 { |
69 SIZE data_size = address - data_space_start; | 94 SIZE data_size = address - data_space_start; |
95 int five_percent = lim_data / 20; | |
70 | 96 |
71 switch (warnlevel) | 97 switch (warnlevel) |
72 { | 98 { |
73 case 0: | 99 case 0: |
74 if (data_size > (lim_data / 4) * 3) | 100 if (data_size > five_percent * 15) |
75 { | 101 { |
76 warnlevel++; | 102 warnlevel++; |
77 (*warn_function) ("Warning: past 75% of memory limit"); | 103 (*warn_function) ("Warning: past 75% of memory limit"); |
78 } | 104 } |
79 break; | 105 break; |
80 | 106 |
81 case 1: | 107 case 1: |
82 if (data_size > (lim_data / 20) * 17) | 108 if (data_size > five_percent * 17) |
83 { | 109 { |
84 warnlevel++; | 110 warnlevel++; |
85 (*warn_function) ("Warning: past 85% of memory limit"); | 111 (*warn_function) ("Warning: past 85% of memory limit"); |
86 } | 112 } |
87 break; | 113 break; |
88 | 114 |
89 case 2: | 115 case 2: |
90 if (data_size > (lim_data / 20) * 19) | 116 if (data_size > five_percent * 19) |
91 { | 117 { |
92 warnlevel++; | 118 warnlevel++; |
93 (*warn_function) ("Warning: past 95% of memory limit"); | 119 (*warn_function) ("Warning: past 95% of memory limit"); |
94 } | 120 } |
95 break; | 121 break; |
97 default: | 123 default: |
98 (*warn_function) ("Warning: past acceptable memory limits"); | 124 (*warn_function) ("Warning: past acceptable memory limits"); |
99 break; | 125 break; |
100 } | 126 } |
101 | 127 |
102 if (EXCEEDS_ELISP_PTR (address)) | 128 /* If we go down below 70% full, issue another 75% warning |
103 memory_full (); | 129 when we go up again. */ |
130 if (data_size < five_percent * 14) | |
131 warnlevel = 0; | |
132 /* If we go down below 80% full, issue another 85% warning | |
133 when we go up again. */ | |
134 else if (warnlevel > 1 && data_size < five_percent * 16) | |
135 warnlevel = 1; | |
136 /* If we go down below 90% full, issue another 95% warning | |
137 when we go up again. */ | |
138 else if (warnlevel > 2 && data_size < five_percent * 18) | |
139 warnlevel = 2; | |
140 | |
141 if (EXCEEDS_LISP_PTR (address)) | |
142 memory_full (); | |
104 } | 143 } |
105 | 144 |
106 /* Functions to get and return memory from the system. */ | 145 /* Functions to get and return memory from the system. */ |
107 | 146 |
108 /* Obtain SIZE bytes of space. If enough space is not presently available | 147 /* Obtain SIZE bytes of space. If enough space is not presently available |
194 #define BLOC_PTR_SIZE (sizeof (struct bp)) | 233 #define BLOC_PTR_SIZE (sizeof (struct bp)) |
195 | 234 |
196 /* Head and tail of the list of relocatable blocs. */ | 235 /* Head and tail of the list of relocatable blocs. */ |
197 static bloc_ptr first_bloc, last_bloc; | 236 static bloc_ptr first_bloc, last_bloc; |
198 | 237 |
199 /* Declared in dispnew.c, this version doesn't screw up if regions | |
200 overlap. */ | |
201 extern void safe_bcopy (); | |
202 | |
203 /* Find the bloc referenced by the address in PTR. Returns a pointer | 238 /* Find the bloc referenced by the address in PTR. Returns a pointer |
204 to that block. */ | 239 to that block. */ |
205 | 240 |
206 static bloc_ptr | 241 static bloc_ptr |
207 find_bloc (ptr) | 242 find_bloc (ptr) |
321 /* Interface routines. */ | 356 /* Interface routines. */ |
322 | 357 |
323 static int use_relocatable_buffers; | 358 static int use_relocatable_buffers; |
324 | 359 |
325 /* Obtain SIZE bytes of storage from the free pool, or the system, as | 360 /* Obtain SIZE bytes of storage from the free pool, or the system, as |
326 neccessary. If relocatable blocs are in use, this means relocating | 361 necessary. If relocatable blocs are in use, this means relocating |
327 them. This function gets plugged into the GNU malloc's __morecore | 362 them. This function gets plugged into the GNU malloc's __morecore |
328 hook. | 363 hook. |
329 | 364 |
330 If we're out of memory, we should return zero, to imitate the other | 365 If we're out of memory, we should return zero, to imitate the other |
331 __morecore hook values - in particular, __default_morecore in the | 366 __morecore hook values - in particular, __default_morecore in the |
378 POINTER *ptr; | 413 POINTER *ptr; |
379 SIZE size; | 414 SIZE size; |
380 { | 415 { |
381 register bloc_ptr new_bloc; | 416 register bloc_ptr new_bloc; |
382 | 417 |
418 if (! r_alloc_initialized) | |
419 r_alloc_init (); | |
420 | |
383 new_bloc = get_bloc (size); | 421 new_bloc = get_bloc (size); |
384 if (new_bloc) | 422 if (new_bloc) |
385 { | 423 { |
386 new_bloc->variable = ptr; | 424 new_bloc->variable = ptr; |
387 *ptr = new_bloc->data; | 425 *ptr = new_bloc->data; |
390 *ptr = 0; | 428 *ptr = 0; |
391 | 429 |
392 return *ptr; | 430 return *ptr; |
393 } | 431 } |
394 | 432 |
395 /* Free a bloc of relocatable storage whose data is pointed to by PTR. */ | 433 /* Free a bloc of relocatable storage whose data is pointed to by PTR. |
434 Store 0 in *PTR to show there's no block allocated. */ | |
396 | 435 |
397 void | 436 void |
398 r_alloc_free (ptr) | 437 r_alloc_free (ptr) |
399 register POINTER *ptr; | 438 register POINTER *ptr; |
400 { | 439 { |
403 dead_bloc = find_bloc (ptr); | 442 dead_bloc = find_bloc (ptr); |
404 if (dead_bloc == NIL_BLOC) | 443 if (dead_bloc == NIL_BLOC) |
405 abort (); | 444 abort (); |
406 | 445 |
407 free_bloc (dead_bloc); | 446 free_bloc (dead_bloc); |
447 *ptr = 0; | |
408 } | 448 } |
409 | 449 |
410 /* Given a pointer at address PTR to relocatable data, resize it to SIZE. | 450 /* Given a pointer at address PTR to relocatable data, resize it to SIZE. |
411 Do this by shifting all blocks above this one up in memory, unless | 451 Do this by shifting all blocks above this one up in memory, unless |
412 SIZE is less than or equal to the current bloc size, in which case | 452 SIZE is less than or equal to the current bloc size, in which case |
448 | 488 |
449 /* The hook `malloc' uses for the function which gets more space | 489 /* The hook `malloc' uses for the function which gets more space |
450 from the system. */ | 490 from the system. */ |
451 extern POINTER (*__morecore) (); | 491 extern POINTER (*__morecore) (); |
452 | 492 |
453 /* A flag to indicate whether we have initialized ralloc yet. For | |
454 Emacs's sake, please do not make this local to malloc_init; on some | |
455 machines, the dumping procedure makes all static variables | |
456 read-only. On these machines, the word static is #defined to be | |
457 the empty string, meaning that malloc_initialized becomes an | |
458 automatic variable, and loses its value each time Emacs is started | |
459 up. */ | |
460 static int malloc_initialized = 0; | |
461 | |
462 /* Intialize various things for memory allocation. */ | 493 /* Intialize various things for memory allocation. */ |
463 | 494 |
495 static void | |
496 r_alloc_init () | |
497 { | |
498 if (r_alloc_initialized) | |
499 return; | |
500 | |
501 r_alloc_initialized = 1; | |
502 __morecore = r_alloc_sbrk; | |
503 | |
504 virtual_break_value = break_value = sbrk (0); | |
505 if (break_value == (POINTER)NULL) | |
506 abort (); | |
507 #if 0 /* The following is unreasonable because warn_func may be 0. */ | |
508 (*warn_func)("memory initialization got 0 from sbrk(0)."); | |
509 #endif | |
510 | |
511 page_break_value = (POINTER) ROUNDUP (break_value); | |
512 /* Clear the rest of the last page; this memory is in our address space | |
513 even though it is after the sbrk value. */ | |
514 bzero (break_value, (page_break_value - break_value)); | |
515 use_relocatable_buffers = 1; | |
516 | |
517 lim_data = 0; | |
518 warnlevel = 0; | |
519 | |
520 get_lim_data (); | |
521 } | |
522 | |
523 /* This is the name Emacs expects to call. */ | |
524 | |
464 void | 525 void |
465 malloc_init (start, warn_func) | 526 memory_warnings (start, warn_func) |
466 POINTER start; | 527 POINTER start; |
467 void (*warn_func) (); | 528 void (*warn_func) (); |
468 { | 529 { |
469 if (start) | 530 if (start) |
470 data_space_start = start; | 531 data_space_start = start; |
471 | 532 else |
472 if (malloc_initialized) | 533 data_space_start = start_of_data (); |
473 return; | 534 |
474 | |
475 malloc_initialized = 1; | |
476 __morecore = r_alloc_sbrk; | |
477 | |
478 virtual_break_value = break_value = sbrk (0); | |
479 if (break_value == (POINTER)NULL) | |
480 (*warn_func)("Malloc initialization returned 0 from sbrk(0)."); | |
481 | |
482 page_break_value = (POINTER) ROUNDUP (break_value); | |
483 bzero (break_value, (page_break_value - break_value)); | |
484 use_relocatable_buffers = 1; | |
485 | |
486 lim_data = 0; | |
487 warnlevel = 0; | |
488 warn_function = warn_func; | 535 warn_function = warn_func; |
489 | 536 } |
490 get_lim_data (); | |
491 } |