changeset 3305:1043bbfa24cf

[xemacs-hg @ 2006-03-26 15:24:25 by crestani] 2006-03-26 Marcus Crestani <crestani@xemacs.org> * alloc.c (malloc_warning): Move function into scope of MALLOC_END, add MALLOC_END. * alloc.c (memory_full): Add memory shortage indication, adjust error messages. * mc-alloc.c: Add memory_shortage. * mc-alloc.c (expand_heap): If memory is short, allocate only the needed pages, not more. * mc-alloc.h: Add memory_shortage.
author crestani
date Sun, 26 Mar 2006 15:24:27 +0000
parents 73051095a712
children 8ce03059a3b8
files src/ChangeLog src/alloc.c src/mc-alloc.c src/mc-alloc.h
diffstat 4 files changed, 81 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sun Mar 26 14:33:39 2006 +0000
+++ b/src/ChangeLog	Sun Mar 26 15:24:27 2006 +0000
@@ -1,3 +1,14 @@
+2006-03-26  Marcus Crestani  <crestani@xemacs.org>
+
+	* alloc.c (malloc_warning): Move function into scope of
+	MALLOC_END, add MALLOC_END.
+	* alloc.c (memory_full): Add memory shortage indication, adjust
+	error messages.
+	* mc-alloc.c: Add memory_shortage.
+	* mc-alloc.c (expand_heap): If memory is short, allocate only the
+	needed pages, not more.
+	* mc-alloc.h: Add memory_shortage.
+
 2006-03-26  Marcus Crestani  <crestani@xemacs.org>
 
 	* alloc.c (make_uninit_string): Use set_lispstringp_direct.
--- a/src/alloc.c	Sun Mar 26 14:33:39 2006 +0000
+++ b/src/alloc.c	Sun Mar 26 15:24:27 2006 +0000
@@ -231,46 +231,6 @@
 }
 #endif /* not NEW_GC */
 
-/* malloc calls this if it finds we are near exhausting storage */
-void
-malloc_warning (const char *str)
-{
-  if (ignore_malloc_warnings)
-    return;
-
-  warn_when_safe
-    (Qmemory, Qemergency,
-     "%s\n"
-     "Killing some buffers may delay running out of memory.\n"
-     "However, certainly by the time you receive the 95%% warning,\n"
-     "you should clean up, kill this Emacs, and start a new one.",
-     str);
-}
-
-/* Called if malloc returns zero */
-DOESNT_RETURN
-memory_full (void)
-{
-  fprintf (stderr, "##### M E M O R Y   F U L L #####\n");
-  /* Force a GC next time eval is called.
-     It's better to loop garbage-collecting (we might reclaim enough
-     to win) than to loop beeping and barfing "Memory exhausted"
-   */
-  consing_since_gc = gc_cons_threshold + 1;
-  recompute_need_to_garbage_collect ();
-#ifndef NEW_GC
-  release_breathing_space ();
-#endif /* not NEW_GC */
-
-  /* Flush some histories which might conceivably contain garbalogical
-     inhibitors.  */
-  if (!NILP (Fboundp (Qvalues)))
-    Fset (Qvalues, Qnil);
-  Vcommand_history = Qnil;
-
-  out_of_memory ("Memory exhausted", Qunbound);
-}
-
 static void
 set_alloc_mins_and_maxes (void *val, Bytecount size)
 {
@@ -354,6 +314,66 @@
   set_alloc_mins_and_maxes (val, size);
 }
 
+/* malloc calls this if it finds we are near exhausting storage */
+void
+malloc_warning (const char *str)
+{
+  if (ignore_malloc_warnings)
+    return;
+
+  /* Remove the malloc lock here, because warn_when_safe may allocate
+     again.  It is safe to remove the malloc lock here, because malloc
+     is already finished (malloc_warning is called via
+     after_morecore_hook -> check_memory_limits -> save_warn_fun ->
+     malloc_warning). */
+  MALLOC_END ();
+
+  warn_when_safe
+    (Qmemory, Qemergency,
+     "%s\n"
+     "Killing some buffers may delay running out of memory.\n"
+     "However, certainly by the time you receive the 95%% warning,\n"
+     "you should clean up, kill this Emacs, and start a new one.",
+     str);
+}
+
+/* Called if malloc returns zero */
+DOESNT_RETURN
+memory_full (void)
+{
+  /* Force a GC next time eval is called.
+     It's better to loop garbage-collecting (we might reclaim enough
+     to win) than to loop beeping and barfing "Memory exhausted"
+   */
+  consing_since_gc = gc_cons_threshold + 1;
+  recompute_need_to_garbage_collect ();
+#ifdef NEW_GC
+  /* Put mc-alloc into memory shortage mode.  This may keep XEmacs
+     alive until the garbage collector can free enough memory to get
+     us out of the memory exhaustion.  If already in memory shortage
+     mode, we are in a loop and hopelessly lost. */
+  if (memory_shortage) 
+    {
+      fprintf (stderr, "Memory full, cannot recover.\n");
+      ABORT ();
+    }
+  fprintf (stderr, 
+	   "Memory full, try to recover.\n"
+	   "You should clean up, kill this Emacs, and start a new one.\n");
+  memory_shortage++;
+#else /* not NEW_GC */
+  release_breathing_space ();
+#endif /* not NEW_GC */
+
+  /* Flush some histories which might conceivably contain garbalogical
+     inhibitors.  */
+  if (!NILP (Fboundp (Qvalues)))
+    Fset (Qvalues, Qnil);
+  Vcommand_history = Qnil;
+
+  out_of_memory ("Memory exhausted", Qunbound);
+}
+
 /* like malloc, calloc, realloc, free but:
 
    -- check for no memory left
--- a/src/mc-alloc.c	Sun Mar 26 14:33:39 2006 +0000
+++ b/src/mc-alloc.c	Sun Mar 26 15:24:27 2006 +0000
@@ -411,6 +411,8 @@
 /*                           MC Allocator                               */
 /************************************************************************/
 
+/* Set to 1 if memory becomes short. */
+EMACS_INT memory_shortage;
 
 /*--- misc functions ---------------------------------------------------*/
 
@@ -1136,9 +1138,12 @@
   void *real_start;
 
   /* determine number of pages the heap should grow */
-  n_pages = needed_pages + (HEAP_SIZE / (PAGE_SIZE * HEAP_GROWTH_DIVISOR));
-  if (n_pages < MIN_HEAP_INCREASE)
-    n_pages = MIN_HEAP_INCREASE;
+  if (memory_shortage)
+    n_pages = needed_pages;
+  else
+    n_pages = max (MIN_HEAP_INCREASE, 
+		   needed_pages
+		   + (HEAP_SIZE / (PAGE_SIZE * HEAP_GROWTH_DIVISOR)));
 
   /* get the real values */
   real_size = (n_pages * PAGE_SIZE) + PAGE_SIZE;
--- a/src/mc-alloc.h	Sun Mar 26 14:33:39 2006 +0000
+++ b/src/mc-alloc.h	Sun Mar 26 15:24:27 2006 +0000
@@ -27,6 +27,8 @@
 
 BEGIN_C_DECLS
 
+/* Set to 1 if memory becomes short. */
+extern EMACS_INT memory_shortage;
 
 
 /* Internal Allocator Functions: */