# HG changeset patch # User crestani # Date 1143386667 0 # Node ID 1043bbfa24cf1b24ba88efa50b14c55cdc27c123 # Parent 73051095a712dd3cd4a7b7f6b5d67c3da0358232 [xemacs-hg @ 2006-03-26 15:24:25 by crestani] 2006-03-26 Marcus Crestani * 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. diff -r 73051095a712 -r 1043bbfa24cf src/ChangeLog --- 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 + + * 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 * alloc.c (make_uninit_string): Use set_lispstringp_direct. diff -r 73051095a712 -r 1043bbfa24cf src/alloc.c --- 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 diff -r 73051095a712 -r 1043bbfa24cf src/mc-alloc.c --- 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; diff -r 73051095a712 -r 1043bbfa24cf src/mc-alloc.h --- 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: */