summaryrefslogtreecommitdiff
path: root/src/alloc.c
diff options
context:
space:
mode:
authorJim Blandy <jimb@redhat.com>1993-03-31 10:55:33 +0000
committerJim Blandy <jimb@redhat.com>1993-03-31 10:55:33 +0000
commit9ac0d9e04198806161ea21e49b0be04e5253fa57 (patch)
tree66bd402e5ebbb6f362446a2baee28245cd953c8f /src/alloc.c
parent357f32fcd0e00337a3c1359a4919e716ed81fe52 (diff)
downloademacs-9ac0d9e04198806161ea21e49b0be04e5253fa57.tar.gz
emacs-9ac0d9e04198806161ea21e49b0be04e5253fa57.tar.bz2
emacs-9ac0d9e04198806161ea21e49b0be04e5253fa57.zip
Put interrupt input blocking in a separate file from xterm.h.
This isn't specific to X, and it allows us to avoid #including xterm.h in files that don't really have anything to do with X. * blockinput.h: New file. * xterm.h (BLOCK_INPUT, UNBLOCK_INPUT, TOTALLY_UNBLOCK_INPUT, UNBLOCK_INPUT_RESIGNAL): These are now in blockinput.h. (x_input_blocked, x_pending_input): Deleted; there are analogs in blockinput.h called interrupt_input_blocked and interrupt_input_pending. * keyboard.c (interrupt_input_blocked, interrupt_input_pending): New variables, used by the macros in blockinput.h. * xterm.c: #include blockinput.h. (x_input_blocked, x_pending_input): Deleted. (XTread_socket): Test and set interrupt_input_blocked and interrupt_input_pending instead of the old variables. * alloc.c, xfaces.c, xfns.c, xmenu.c, xselect.c, keymap.c: #include blockinput.h. * eval.c: #include blockinput.h instead of xterm.h. * keyboard.c: #include blockinput.h. (input_poll_signal): Just test interrupt_input_blocked, instead of testing HAVE_X_WINDOWS and x_input_blocked. Block the processing of interrupt input while we're manipulating the malloc heap. * alloc.c: (xfree): New function, to make it easy to free things safely. (xmalloc, xrealloc): Block X input while doing the deed. (VALIDATE_LISP_STORAGE, gc_sweep, compact_strings): Use xfree instead of free. (uninterrupt_malloc): New function, to install input-blocking hooks into the GNU malloc routines. * emacs.c [not SYSTEM_MALLOC] (main): Call uninterrupt_malloc on startup. * alloc.c: (make_interval, make_float, Fcons, Fmake_vector, Fmake_symbol, Fmake_marker, make_uninit_string, Fgarbage_collect): Use xmalloc instead of malloc; don't bother to check if out of memory here. (Fgarbage_collect): Call xrealloc instead of realloc. * buffer.c: Use xmalloc and xfree instead of malloc and free; don't bother to check if out of memory here. (Fget_buffer_create): Put BLOCK_INPUT/UNBLOCK_INPUT pair around calls to ralloc routines. * insdel.c: Same. * lisp.h (xfree): New extern declaration. * xfaces.c (xfree): Don't #define this to be free; use the definition in alloc.c. * dispnew.c, doc.c, doprnt.c, fileio.c, lread.c, term.c, xfns.c, xmenu.c, xterm.c: Use xfree instead of free. * hftctl.c: Use xfree and xmalloc instead of free and malloc. * keymap.c (current_minor_maps): BLOCK_INPUT while calling realloc and malloc. * search.c: Since the regexp routines can malloc, BLOCK_INPUT while runing them. #include blockinput.h. * sysdep.c: #include blockinput.h. Call xfree and xmalloc instead of free and malloc. BLOCK_INPUT around routines which we know will call malloc. ymakefile (keyboard.o, keymap.o, search.o, sysdep.o, xfaces.o, xfns.o, xmenu.o, xterm.o, xselect.o, alloc.o, eval.o): Note that these depend on blockinput.h.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c131
1 files changed, 103 insertions, 28 deletions
diff --git a/src/alloc.c b/src/alloc.c
index bf4d1898cda..46941e58181 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "buffer.h"
#include "window.h"
#include "frame.h"
+#include "blockinput.h"
#endif
#include "syssignal.h"
@@ -43,7 +44,7 @@ do \
XSET (val, Lisp_Cons, (char *) address + size); \
if ((char *) XCONS (val) != (char *) address + size) \
{ \
- free (address); \
+ xfree (address); \
memory_full (); \
} \
} while (0)
@@ -149,7 +150,7 @@ memory_full ()
error ("Memory exhausted");
}
-/* like malloc and realloc but check for no memory left */
+/* like malloc routines but check for no memory and block interrupt input. */
long *
xmalloc (size)
@@ -157,7 +158,9 @@ xmalloc (size)
{
register long *val;
+ BLOCK_INPUT;
val = (long *) malloc (size);
+ UNBLOCK_INPUT;
if (!val && size) memory_full ();
return val;
@@ -170,16 +173,99 @@ xrealloc (block, size)
{
register long *val;
+ BLOCK_INPUT;
/* We must call malloc explicitly when BLOCK is 0, since some
reallocs don't do this. */
if (! block)
val = (long *) malloc (size);
else
val = (long *) realloc (block, size);
+ UNBLOCK_INPUT;
if (!val && size) memory_full ();
return val;
}
+
+void
+xfree (block)
+ long *block;
+{
+ BLOCK_INPUT;
+ free (block);
+ UNBLOCK_INPUT;
+}
+
+
+/* Arranging to disable input signals while we're in malloc.
+
+ This only works with GNU malloc. To help out systems which can't
+ use GNU malloc, all the calls to malloc, realloc, and free
+ elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT
+ pairs; unfortunately, we have no idea what C library functions
+ might call malloc, so we can't really protect them unless you're
+ using GNU malloc. Fortunately, most of the major operating can use
+ GNU malloc. */
+
+#ifndef SYSTEM_MALLOC
+static void (*__malloc_hook) (), (*old_malloc_hook) ();
+static void (*__realloc_hook) (), (*old_realloc_hook) ();
+static void (*__free_hook) (), (*old_free_hook) ();
+
+static void
+emacs_blocked_free (ptr)
+ void *ptr;
+{
+ BLOCK_INPUT;
+ __free_hook = old_free_hook;
+ free (ptr);
+ __free_hook = &emacs_blocked_free;
+ UNBLOCK_INPUT;
+}
+
+static void *
+emacs_blocked_malloc (size)
+ unsigned size;
+{
+ void *value;
+
+ BLOCK_INPUT;
+ __malloc_hook = old_malloc_hook;
+ value = malloc (size);
+ __malloc_hook = &emacs_blocked_malloc;
+ UNBLOCK_INPUT;
+
+ return value;
+}
+
+static void *
+emacs_blocked_realloc (ptr, size)
+ void *ptr;
+ unsigned size;
+{
+ void *value;
+
+ BLOCK_INPUT;
+ __realloc_hook = old_realloc_hook;
+ value = realloc (ptr, size);
+ __realloc_hook = &emacs_blocked_realloc;
+ UNBLOCK_INPUT;
+
+ return value;
+}
+
+void
+uninterrupt_malloc ()
+{
+ old_free_hook = __free_hook;
+ __free_hook = &emacs_blocked_free;
+
+ old_malloc_hook = __malloc_hook;
+ __malloc_hook = &emacs_blocked_malloc;
+
+ old_realloc_hook = __realloc_hook;
+ __realloc_hook = &emacs_blocked_realloc;
+}
+#endif
/* Interval allocation. */
@@ -226,10 +312,7 @@ make_interval ()
if (interval_block_index == INTERVAL_BLOCK_SIZE)
{
register struct interval_block *newi
- = (struct interval_block *) malloc (sizeof (struct interval_block));
-
- if (!newi)
- memory_full ();
+ = (struct interval_block *) xmalloc (sizeof (struct interval_block));
VALIDATE_LISP_STORAGE (newi, sizeof *newi);
newi->next = interval_block;
@@ -352,8 +435,7 @@ make_float (float_value)
{
if (float_block_index == FLOAT_BLOCK_SIZE)
{
- register struct float_block *new = (struct float_block *) malloc (sizeof (struct float_block));
- if (!new) memory_full ();
+ register struct float_block *new = (struct float_block *) xmalloc (sizeof (struct float_block));
VALIDATE_LISP_STORAGE (new, sizeof *new);
new->next = float_block;
float_block = new;
@@ -427,8 +509,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
{
if (cons_block_index == CONS_BLOCK_SIZE)
{
- register struct cons_block *new = (struct cons_block *) malloc (sizeof (struct cons_block));
- if (!new) memory_full ();
+ register struct cons_block *new = (struct cons_block *) xmalloc (sizeof (struct cons_block));
VALIDATE_LISP_STORAGE (new, sizeof *new);
new->next = cons_block;
cons_block = new;
@@ -498,9 +579,7 @@ See also the function `vector'.")
length = wrong_type_argument (Qnatnump, length);
sizei = XINT (length);
- p = (struct Lisp_Vector *) malloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object));
- if (p == 0)
- memory_full ();
+ p = (struct Lisp_Vector *) xmalloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object));
VALIDATE_LISP_STORAGE (p, 0);
XSET (vector, Lisp_Vector, p);
@@ -617,8 +696,7 @@ Its value and function definition are void, and its property list is nil.")
{
if (symbol_block_index == SYMBOL_BLOCK_SIZE)
{
- struct symbol_block *new = (struct symbol_block *) malloc (sizeof (struct symbol_block));
- if (!new) memory_full ();
+ struct symbol_block *new = (struct symbol_block *) xmalloc (sizeof (struct symbol_block));
VALIDATE_LISP_STORAGE (new, sizeof *new);
new->next = symbol_block;
symbol_block = new;
@@ -680,8 +758,7 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
{
if (marker_block_index == MARKER_BLOCK_SIZE)
{
- struct marker_block *new = (struct marker_block *) malloc (sizeof (struct marker_block));
- if (!new) memory_full ();
+ struct marker_block *new = (struct marker_block *) xmalloc (sizeof (struct marker_block));
VALIDATE_LISP_STORAGE (new, sizeof *new);
new->next = marker_block;
marker_block = new;
@@ -830,9 +907,8 @@ make_uninit_string (length)
/* This string gets its own string block */
{
register struct string_block *new
- = (struct string_block *) malloc (sizeof (struct string_block_head) + fullsize);
+ = (struct string_block *) xmalloc (sizeof (struct string_block_head) + fullsize);
VALIDATE_LISP_STORAGE (new, 0);
- if (!new) memory_full ();
consing_since_gc += sizeof (struct string_block_head) + fullsize;
new->pos = fullsize;
new->next = large_string_blocks;
@@ -844,8 +920,7 @@ make_uninit_string (length)
/* Make a new current string block and start it off with this string */
{
register struct string_block *new
- = (struct string_block *) malloc (sizeof (struct string_block));
- if (!new) memory_full ();
+ = (struct string_block *) xmalloc (sizeof (struct string_block));
VALIDATE_LISP_STORAGE (new, sizeof *new);
consing_since_gc += sizeof (struct string_block);
current_string_block->next = new;
@@ -1149,9 +1224,9 @@ Garbage collection happens automatically if you cons more than\n\
if (i < MAX_SAVE_STACK)
{
if (stack_copy == 0)
- stack_copy = (char *) malloc (stack_copy_size = i);
+ stack_copy = (char *) xmalloc (stack_copy_size = i);
else if (stack_copy_size < i)
- stack_copy = (char *) realloc (stack_copy, (stack_copy_size = i));
+ stack_copy = (char *) xrealloc (stack_copy, (stack_copy_size = i));
if (stack_copy)
{
if ((int) (&stack_top_variable - stack_bottom) > 0)
@@ -1804,7 +1879,7 @@ gc_sweep ()
else
all_buffers = buffer->next;
next = buffer->next;
- free (buffer);
+ xfree (buffer);
buffer = next;
}
else
@@ -1845,7 +1920,7 @@ gc_sweep ()
else
all_vectors = vector->next;
next = vector->next;
- free (vector);
+ xfree (vector);
vector = next;
}
else
@@ -1868,7 +1943,7 @@ gc_sweep ()
else
large_string_blocks = sb->next;
next = sb->next;
- free (sb);
+ xfree (sb);
sb = next;
}
else
@@ -1983,7 +2058,7 @@ compact_strings ()
while (from_sb)
{
to_sb = from_sb->next;
- free (from_sb);
+ xfree (from_sb);
from_sb = to_sb;
}
@@ -1998,7 +2073,7 @@ compact_strings ()
{
if (from_sb->next = to_sb->next)
from_sb->next->prev = from_sb;
- free (to_sb);
+ xfree (to_sb);
}
else
from_sb = to_sb;