aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ralloc.c109
1 files changed, 77 insertions, 32 deletions
diff --git a/src/ralloc.c b/src/ralloc.c
index c43218eaefc..3f65c063850 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -23,14 +23,39 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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. */
32extern void safe_bcopy ();
33#endif
34
35#ifndef emacs
36#include <stddef.h>
37typedef size_t SIZE;
38typedef 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. */
56static int r_alloc_initialized = 0;
57
58static 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
@@ -50,7 +75,7 @@ static POINTER page_break_value;
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. */
@@ -67,11 +92,12 @@ 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");
@@ -79,7 +105,7 @@ check_memory_limits (address)
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");
@@ -87,7 +113,7 @@ check_memory_limits (address)
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");
@@ -99,8 +125,21 @@ check_memory_limits (address)
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. */
@@ -196,10 +235,6 @@ typedef struct bp
196/* Head and tail of the list of relocatable blocs. */ 235/* Head and tail of the list of relocatable blocs. */
197static bloc_ptr first_bloc, last_bloc; 236static bloc_ptr first_bloc, last_bloc;
198 237
199/* Declared in dispnew.c, this version doesn't screw up if regions
200 overlap. */
201extern 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
@@ -323,7 +358,7 @@ free_bloc (bloc)
323static int use_relocatable_buffers; 358static 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
@@ -380,6 +415,9 @@ r_alloc (ptr, 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 {
@@ -392,7 +430,8 @@ r_alloc (ptr, size)
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
397void 436void
398r_alloc_free (ptr) 437r_alloc_free (ptr)
@@ -405,6 +444,7 @@ r_alloc_free (ptr)
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.
@@ -450,42 +490,47 @@ r_re_alloc (ptr, size)
450 from the system. */ 490 from the system. */
451extern POINTER (*__morecore) (); 491extern 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. */
460static int malloc_initialized = 0;
461
462/* Intialize various things for memory allocation. */ 493/* Intialize various things for memory allocation. */
463 494
464void 495static void
465malloc_init (start, warn_func) 496r_alloc_init ()
466 POINTER start;
467 void (*warn_func) ();
468{ 497{
469 if (start) 498 if (r_alloc_initialized)
470 data_space_start = start;
471
472 if (malloc_initialized)
473 return; 499 return;
474 500
475 malloc_initialized = 1; 501 r_alloc_initialized = 1;
476 __morecore = r_alloc_sbrk; 502 __morecore = r_alloc_sbrk;
477 503
478 virtual_break_value = break_value = sbrk (0); 504 virtual_break_value = break_value = sbrk (0);
479 if (break_value == (POINTER)NULL) 505 if (break_value == (POINTER)NULL)
480 (*warn_func)("Malloc initialization returned 0 from sbrk(0)."); 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
481 510
482 page_break_value = (POINTER) ROUNDUP (break_value); 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. */
483 bzero (break_value, (page_break_value - break_value)); 514 bzero (break_value, (page_break_value - break_value));
484 use_relocatable_buffers = 1; 515 use_relocatable_buffers = 1;
485 516
486 lim_data = 0; 517 lim_data = 0;
487 warnlevel = 0; 518 warnlevel = 0;
488 warn_function = warn_func;
489 519
490 get_lim_data (); 520 get_lim_data ();
491} 521}
522
523/* This is the name Emacs expects to call. */
524
525void
526memory_warnings (start, warn_func)
527 POINTER start;
528 void (*warn_func) ();
529{
530 if (start)
531 data_space_start = start;
532 else
533 data_space_start = start_of_data ();
534
535 warn_function = warn_func;
536}