changeset 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 517c3893ec5b
children cb0830eb1ce7
files src/ralloc.c
diffstat 1 files changed, 85 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/ralloc.c	Sun Oct 11 06:44:42 1992 +0000
+++ b/src/ralloc.c	Sun Oct 11 20:37:32 1992 +0000
@@ -23,14 +23,39 @@
    rather than all of them.  This means allowing for a possible
    hole between the first bloc and the end of malloc storage. */
 
+#ifdef emacs
 #include "config.h"
 #include "lisp.h"		/* Needed for VALBITS.  */
+
+/* Declared in dispnew.c, this version doesn't screw up if regions
+   overlap.  */
+extern void safe_bcopy ();
+#endif
+
+#ifndef emacs
+#include <stddef.h>
+typedef size_t SIZE;
+typedef void *POINTER;
+#define EXCEEDS_LISP_PTR(x) 0
+
+#define safe_bcopy(x, y, z) memmove (y, x, z)
+#endif
+
 #undef NULL
 #include "mem_limits.h"
 #include "getpagesize.h"
 
 #define NIL ((POINTER) 0)
 
+/* A flag to indicate whether we have initialized ralloc yet.  For
+   Emacs's sake, please do not make this local to malloc_init; on some
+   machines, the dumping procedure makes all static variables
+   read-only.  On these machines, the word static is #defined to be
+   the empty string, meaning that r_alloc_initialized becomes an
+   automatic variable, and loses its value each time Emacs is started up.  */
+static int r_alloc_initialized = 0;
+
+static void r_alloc_init ();
 
 /* Declarations for working with the malloc, ralloc, and system breaks.  */
 
@@ -50,7 +75,7 @@
    by changing the definition of PAGE. */
 #define PAGE (getpagesize ())
 #define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0)
-#define ROUNDUP(size) (((unsigned int) (size) + PAGE) & ~(PAGE - 1))
+#define ROUNDUP(size) (((unsigned int) (size) + PAGE - 1) & ~(PAGE - 1))
 #define ROUND_TO_PAGE(addr) (addr & (~(PAGE - 1)))
 
 /* Managing "almost out of memory" warnings.  */
@@ -67,11 +92,12 @@
      POINTER address;
 {
   SIZE data_size = address - data_space_start;
+  int five_percent = lim_data / 20;
 
   switch (warnlevel)
     {
     case 0: 
-      if (data_size > (lim_data / 4) * 3)
+      if (data_size > five_percent * 15)
 	{
 	  warnlevel++;
 	  (*warn_function) ("Warning: past 75% of memory limit");
@@ -79,7 +105,7 @@
       break;
 
     case 1: 
-      if (data_size > (lim_data / 20) * 17)
+      if (data_size > five_percent * 17)
 	{
 	  warnlevel++;
 	  (*warn_function) ("Warning: past 85% of memory limit");
@@ -87,7 +113,7 @@
       break;
 
     case 2: 
-      if (data_size > (lim_data / 20) * 19)
+      if (data_size > five_percent * 19)
 	{
 	  warnlevel++;
 	  (*warn_function) ("Warning: past 95% of memory limit");
@@ -99,8 +125,21 @@
       break;
     }
 
-    if (EXCEEDS_ELISP_PTR (address))
-      memory_full ();
+  /* If we go down below 70% full, issue another 75% warning
+     when we go up again.  */
+  if (data_size < five_percent * 14)
+    warnlevel = 0;
+  /* If we go down below 80% full, issue another 85% warning
+     when we go up again.  */
+  else if (warnlevel > 1 && data_size < five_percent * 16)
+    warnlevel = 1;
+  /* If we go down below 90% full, issue another 95% warning
+     when we go up again.  */
+  else if (warnlevel > 2 && data_size < five_percent * 18)
+    warnlevel = 2;
+
+  if (EXCEEDS_LISP_PTR (address))
+    memory_full ();
 }
 
 /* Functions to get and return memory from the system.  */
@@ -196,10 +235,6 @@
 /* Head and tail of the list of relocatable blocs. */
 static bloc_ptr first_bloc, last_bloc;
 
-/* Declared in dispnew.c, this version doesn't screw up if regions
-   overlap.  */
-extern void safe_bcopy ();
-
 /* Find the bloc referenced by the address in PTR.  Returns a pointer
    to that block. */
 
@@ -323,7 +358,7 @@
 static int use_relocatable_buffers;
 
 /* Obtain SIZE bytes of storage from the free pool, or the system, as
-   neccessary.  If relocatable blocs are in use, this means relocating
+   necessary.  If relocatable blocs are in use, this means relocating
    them.  This function gets plugged into the GNU malloc's __morecore
    hook.
 
@@ -380,6 +415,9 @@
 {
   register bloc_ptr new_bloc;
 
+  if (! r_alloc_initialized)
+    r_alloc_init ();
+
   new_bloc = get_bloc (size);
   if (new_bloc)
     {
@@ -392,7 +430,8 @@
   return *ptr;
 }
 
-/* Free a bloc of relocatable storage whose data is pointed to by PTR. */
+/* Free a bloc of relocatable storage whose data is pointed to by PTR.
+   Store 0 in *PTR to show there's no block allocated.  */
 
 void
 r_alloc_free (ptr)
@@ -405,6 +444,7 @@
     abort ();
 
   free_bloc (dead_bloc);
+  *ptr = 0;
 }
 
 /* Given a pointer at address PTR to relocatable data, resize it to SIZE.
@@ -450,42 +490,47 @@
    from the system.  */
 extern POINTER (*__morecore) ();
 
-/* A flag to indicate whether we have initialized ralloc yet.  For
-   Emacs's sake, please do not make this local to malloc_init; on some
-   machines, the dumping procedure makes all static variables
-   read-only.  On these machines, the word static is #defined to be
-   the empty string, meaning that malloc_initialized becomes an
-   automatic variable, and loses its value each time Emacs is started
-   up.  */
-static int malloc_initialized = 0;
-
 /* Intialize various things for memory allocation. */
 
+static void
+r_alloc_init ()
+{
+  if (r_alloc_initialized)
+    return;
+
+  r_alloc_initialized = 1;
+  __morecore = r_alloc_sbrk;
+
+  virtual_break_value = break_value = sbrk (0);
+  if (break_value == (POINTER)NULL)
+    abort ();
+#if 0 /* The following is unreasonable because warn_func may be 0.  */
+    (*warn_func)("memory initialization got 0 from sbrk(0).");
+#endif
+
+  page_break_value = (POINTER) ROUNDUP (break_value);
+  /* Clear the rest of the last page; this memory is in our address space
+     even though it is after the sbrk value.  */
+  bzero (break_value, (page_break_value - break_value));
+  use_relocatable_buffers = 1;
+
+  lim_data = 0;
+  warnlevel = 0;
+
+  get_lim_data ();
+}
+
+/* This is the name Emacs expects to call.  */
+
 void
-malloc_init (start, warn_func)
+memory_warnings (start, warn_func)
      POINTER start;
      void (*warn_func) ();
 {
   if (start)
     data_space_start = start;
-
-  if (malloc_initialized)
-    return;
-
-  malloc_initialized = 1;
-  __morecore = r_alloc_sbrk;
-
-  virtual_break_value = break_value = sbrk (0);
-  if (break_value == (POINTER)NULL)
-    (*warn_func)("Malloc initialization returned 0 from sbrk(0).");
+  else
+    data_space_start = start_of_data ();
 
-  page_break_value = (POINTER) ROUNDUP (break_value);
-  bzero (break_value, (page_break_value - break_value));
-  use_relocatable_buffers = 1;
-
-  lim_data = 0;
-  warnlevel = 0;
   warn_function = warn_func;
-
-  get_lim_data ();
 }