diff options
| author | Jim Blandy | 1993-03-31 10:55:33 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-03-31 10:55:33 +0000 |
| commit | 9ac0d9e04198806161ea21e49b0be04e5253fa57 (patch) | |
| tree | 66bd402e5ebbb6f362446a2baee28245cd953c8f /src/alloc.c | |
| parent | 357f32fcd0e00337a3c1359a4919e716ed81fe52 (diff) | |
| download | emacs-9ac0d9e04198806161ea21e49b0be04e5253fa57.tar.gz 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.c | 131 |
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. */ | |||
| 26 | #include "buffer.h" | 26 | #include "buffer.h" |
| 27 | #include "window.h" | 27 | #include "window.h" |
| 28 | #include "frame.h" | 28 | #include "frame.h" |
| 29 | #include "blockinput.h" | ||
| 29 | #endif | 30 | #endif |
| 30 | 31 | ||
| 31 | #include "syssignal.h" | 32 | #include "syssignal.h" |
| @@ -43,7 +44,7 @@ do \ | |||
| 43 | XSET (val, Lisp_Cons, (char *) address + size); \ | 44 | XSET (val, Lisp_Cons, (char *) address + size); \ |
| 44 | if ((char *) XCONS (val) != (char *) address + size) \ | 45 | if ((char *) XCONS (val) != (char *) address + size) \ |
| 45 | { \ | 46 | { \ |
| 46 | free (address); \ | 47 | xfree (address); \ |
| 47 | memory_full (); \ | 48 | memory_full (); \ |
| 48 | } \ | 49 | } \ |
| 49 | } while (0) | 50 | } while (0) |
| @@ -149,7 +150,7 @@ memory_full () | |||
| 149 | error ("Memory exhausted"); | 150 | error ("Memory exhausted"); |
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | /* like malloc and realloc but check for no memory left */ | 153 | /* like malloc routines but check for no memory and block interrupt input. */ |
| 153 | 154 | ||
| 154 | long * | 155 | long * |
| 155 | xmalloc (size) | 156 | xmalloc (size) |
| @@ -157,7 +158,9 @@ xmalloc (size) | |||
| 157 | { | 158 | { |
| 158 | register long *val; | 159 | register long *val; |
| 159 | 160 | ||
| 161 | BLOCK_INPUT; | ||
| 160 | val = (long *) malloc (size); | 162 | val = (long *) malloc (size); |
| 163 | UNBLOCK_INPUT; | ||
| 161 | 164 | ||
| 162 | if (!val && size) memory_full (); | 165 | if (!val && size) memory_full (); |
| 163 | return val; | 166 | return val; |
| @@ -170,16 +173,99 @@ xrealloc (block, size) | |||
| 170 | { | 173 | { |
| 171 | register long *val; | 174 | register long *val; |
| 172 | 175 | ||
| 176 | BLOCK_INPUT; | ||
| 173 | /* We must call malloc explicitly when BLOCK is 0, since some | 177 | /* We must call malloc explicitly when BLOCK is 0, since some |
| 174 | reallocs don't do this. */ | 178 | reallocs don't do this. */ |
| 175 | if (! block) | 179 | if (! block) |
| 176 | val = (long *) malloc (size); | 180 | val = (long *) malloc (size); |
| 177 | else | 181 | else |
| 178 | val = (long *) realloc (block, size); | 182 | val = (long *) realloc (block, size); |
| 183 | UNBLOCK_INPUT; | ||
| 179 | 184 | ||
| 180 | if (!val && size) memory_full (); | 185 | if (!val && size) memory_full (); |
| 181 | return val; | 186 | return val; |
| 182 | } | 187 | } |
| 188 | |||
| 189 | void | ||
| 190 | xfree (block) | ||
| 191 | long *block; | ||
| 192 | { | ||
| 193 | BLOCK_INPUT; | ||
| 194 | free (block); | ||
| 195 | UNBLOCK_INPUT; | ||
| 196 | } | ||
| 197 | |||
| 198 | |||
| 199 | /* Arranging to disable input signals while we're in malloc. | ||
| 200 | |||
| 201 | This only works with GNU malloc. To help out systems which can't | ||
| 202 | use GNU malloc, all the calls to malloc, realloc, and free | ||
| 203 | elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT | ||
| 204 | pairs; unfortunately, we have no idea what C library functions | ||
| 205 | might call malloc, so we can't really protect them unless you're | ||
| 206 | using GNU malloc. Fortunately, most of the major operating can use | ||
| 207 | GNU malloc. */ | ||
| 208 | |||
| 209 | #ifndef SYSTEM_MALLOC | ||
| 210 | static void (*__malloc_hook) (), (*old_malloc_hook) (); | ||
| 211 | static void (*__realloc_hook) (), (*old_realloc_hook) (); | ||
| 212 | static void (*__free_hook) (), (*old_free_hook) (); | ||
| 213 | |||
| 214 | static void | ||
| 215 | emacs_blocked_free (ptr) | ||
| 216 | void *ptr; | ||
| 217 | { | ||
| 218 | BLOCK_INPUT; | ||
| 219 | __free_hook = old_free_hook; | ||
| 220 | free (ptr); | ||
| 221 | __free_hook = &emacs_blocked_free; | ||
| 222 | UNBLOCK_INPUT; | ||
| 223 | } | ||
| 224 | |||
| 225 | static void * | ||
| 226 | emacs_blocked_malloc (size) | ||
| 227 | unsigned size; | ||
| 228 | { | ||
| 229 | void *value; | ||
| 230 | |||
| 231 | BLOCK_INPUT; | ||
| 232 | __malloc_hook = old_malloc_hook; | ||
| 233 | value = malloc (size); | ||
| 234 | __malloc_hook = &emacs_blocked_malloc; | ||
| 235 | UNBLOCK_INPUT; | ||
| 236 | |||
| 237 | return value; | ||
| 238 | } | ||
| 239 | |||
| 240 | static void * | ||
| 241 | emacs_blocked_realloc (ptr, size) | ||
| 242 | void *ptr; | ||
| 243 | unsigned size; | ||
| 244 | { | ||
| 245 | void *value; | ||
| 246 | |||
| 247 | BLOCK_INPUT; | ||
| 248 | __realloc_hook = old_realloc_hook; | ||
| 249 | value = realloc (ptr, size); | ||
| 250 | __realloc_hook = &emacs_blocked_realloc; | ||
| 251 | UNBLOCK_INPUT; | ||
| 252 | |||
| 253 | return value; | ||
| 254 | } | ||
| 255 | |||
| 256 | void | ||
| 257 | uninterrupt_malloc () | ||
| 258 | { | ||
| 259 | old_free_hook = __free_hook; | ||
| 260 | __free_hook = &emacs_blocked_free; | ||
| 261 | |||
| 262 | old_malloc_hook = __malloc_hook; | ||
| 263 | __malloc_hook = &emacs_blocked_malloc; | ||
| 264 | |||
| 265 | old_realloc_hook = __realloc_hook; | ||
| 266 | __realloc_hook = &emacs_blocked_realloc; | ||
| 267 | } | ||
| 268 | #endif | ||
| 183 | 269 | ||
| 184 | /* Interval allocation. */ | 270 | /* Interval allocation. */ |
| 185 | 271 | ||
| @@ -226,10 +312,7 @@ make_interval () | |||
| 226 | if (interval_block_index == INTERVAL_BLOCK_SIZE) | 312 | if (interval_block_index == INTERVAL_BLOCK_SIZE) |
| 227 | { | 313 | { |
| 228 | register struct interval_block *newi | 314 | register struct interval_block *newi |
| 229 | = (struct interval_block *) malloc (sizeof (struct interval_block)); | 315 | = (struct interval_block *) xmalloc (sizeof (struct interval_block)); |
| 230 | |||
| 231 | if (!newi) | ||
| 232 | memory_full (); | ||
| 233 | 316 | ||
| 234 | VALIDATE_LISP_STORAGE (newi, sizeof *newi); | 317 | VALIDATE_LISP_STORAGE (newi, sizeof *newi); |
| 235 | newi->next = interval_block; | 318 | newi->next = interval_block; |
| @@ -352,8 +435,7 @@ make_float (float_value) | |||
| 352 | { | 435 | { |
| 353 | if (float_block_index == FLOAT_BLOCK_SIZE) | 436 | if (float_block_index == FLOAT_BLOCK_SIZE) |
| 354 | { | 437 | { |
| 355 | register struct float_block *new = (struct float_block *) malloc (sizeof (struct float_block)); | 438 | register struct float_block *new = (struct float_block *) xmalloc (sizeof (struct float_block)); |
| 356 | if (!new) memory_full (); | ||
| 357 | VALIDATE_LISP_STORAGE (new, sizeof *new); | 439 | VALIDATE_LISP_STORAGE (new, sizeof *new); |
| 358 | new->next = float_block; | 440 | new->next = float_block; |
| 359 | float_block = new; | 441 | float_block = new; |
| @@ -427,8 +509,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 427 | { | 509 | { |
| 428 | if (cons_block_index == CONS_BLOCK_SIZE) | 510 | if (cons_block_index == CONS_BLOCK_SIZE) |
| 429 | { | 511 | { |
| 430 | register struct cons_block *new = (struct cons_block *) malloc (sizeof (struct cons_block)); | 512 | register struct cons_block *new = (struct cons_block *) xmalloc (sizeof (struct cons_block)); |
| 431 | if (!new) memory_full (); | ||
| 432 | VALIDATE_LISP_STORAGE (new, sizeof *new); | 513 | VALIDATE_LISP_STORAGE (new, sizeof *new); |
| 433 | new->next = cons_block; | 514 | new->next = cons_block; |
| 434 | cons_block = new; | 515 | cons_block = new; |
| @@ -498,9 +579,7 @@ See also the function `vector'.") | |||
| 498 | length = wrong_type_argument (Qnatnump, length); | 579 | length = wrong_type_argument (Qnatnump, length); |
| 499 | sizei = XINT (length); | 580 | sizei = XINT (length); |
| 500 | 581 | ||
| 501 | p = (struct Lisp_Vector *) malloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object)); | 582 | p = (struct Lisp_Vector *) xmalloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object)); |
| 502 | if (p == 0) | ||
| 503 | memory_full (); | ||
| 504 | VALIDATE_LISP_STORAGE (p, 0); | 583 | VALIDATE_LISP_STORAGE (p, 0); |
| 505 | 584 | ||
| 506 | XSET (vector, Lisp_Vector, p); | 585 | XSET (vector, Lisp_Vector, p); |
| @@ -617,8 +696,7 @@ Its value and function definition are void, and its property list is nil.") | |||
| 617 | { | 696 | { |
| 618 | if (symbol_block_index == SYMBOL_BLOCK_SIZE) | 697 | if (symbol_block_index == SYMBOL_BLOCK_SIZE) |
| 619 | { | 698 | { |
| 620 | struct symbol_block *new = (struct symbol_block *) malloc (sizeof (struct symbol_block)); | 699 | struct symbol_block *new = (struct symbol_block *) xmalloc (sizeof (struct symbol_block)); |
| 621 | if (!new) memory_full (); | ||
| 622 | VALIDATE_LISP_STORAGE (new, sizeof *new); | 700 | VALIDATE_LISP_STORAGE (new, sizeof *new); |
| 623 | new->next = symbol_block; | 701 | new->next = symbol_block; |
| 624 | symbol_block = new; | 702 | symbol_block = new; |
| @@ -680,8 +758,7 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 680 | { | 758 | { |
| 681 | if (marker_block_index == MARKER_BLOCK_SIZE) | 759 | if (marker_block_index == MARKER_BLOCK_SIZE) |
| 682 | { | 760 | { |
| 683 | struct marker_block *new = (struct marker_block *) malloc (sizeof (struct marker_block)); | 761 | struct marker_block *new = (struct marker_block *) xmalloc (sizeof (struct marker_block)); |
| 684 | if (!new) memory_full (); | ||
| 685 | VALIDATE_LISP_STORAGE (new, sizeof *new); | 762 | VALIDATE_LISP_STORAGE (new, sizeof *new); |
| 686 | new->next = marker_block; | 763 | new->next = marker_block; |
| 687 | marker_block = new; | 764 | marker_block = new; |
| @@ -830,9 +907,8 @@ make_uninit_string (length) | |||
| 830 | /* This string gets its own string block */ | 907 | /* This string gets its own string block */ |
| 831 | { | 908 | { |
| 832 | register struct string_block *new | 909 | register struct string_block *new |
| 833 | = (struct string_block *) malloc (sizeof (struct string_block_head) + fullsize); | 910 | = (struct string_block *) xmalloc (sizeof (struct string_block_head) + fullsize); |
| 834 | VALIDATE_LISP_STORAGE (new, 0); | 911 | VALIDATE_LISP_STORAGE (new, 0); |
| 835 | if (!new) memory_full (); | ||
| 836 | consing_since_gc += sizeof (struct string_block_head) + fullsize; | 912 | consing_since_gc += sizeof (struct string_block_head) + fullsize; |
| 837 | new->pos = fullsize; | 913 | new->pos = fullsize; |
| 838 | new->next = large_string_blocks; | 914 | new->next = large_string_blocks; |
| @@ -844,8 +920,7 @@ make_uninit_string (length) | |||
| 844 | /* Make a new current string block and start it off with this string */ | 920 | /* Make a new current string block and start it off with this string */ |
| 845 | { | 921 | { |
| 846 | register struct string_block *new | 922 | register struct string_block *new |
| 847 | = (struct string_block *) malloc (sizeof (struct string_block)); | 923 | = (struct string_block *) xmalloc (sizeof (struct string_block)); |
| 848 | if (!new) memory_full (); | ||
| 849 | VALIDATE_LISP_STORAGE (new, sizeof *new); | 924 | VALIDATE_LISP_STORAGE (new, sizeof *new); |
| 850 | consing_since_gc += sizeof (struct string_block); | 925 | consing_since_gc += sizeof (struct string_block); |
| 851 | current_string_block->next = new; | 926 | current_string_block->next = new; |
| @@ -1149,9 +1224,9 @@ Garbage collection happens automatically if you cons more than\n\ | |||
| 1149 | if (i < MAX_SAVE_STACK) | 1224 | if (i < MAX_SAVE_STACK) |
| 1150 | { | 1225 | { |
| 1151 | if (stack_copy == 0) | 1226 | if (stack_copy == 0) |
| 1152 | stack_copy = (char *) malloc (stack_copy_size = i); | 1227 | stack_copy = (char *) xmalloc (stack_copy_size = i); |
| 1153 | else if (stack_copy_size < i) | 1228 | else if (stack_copy_size < i) |
| 1154 | stack_copy = (char *) realloc (stack_copy, (stack_copy_size = i)); | 1229 | stack_copy = (char *) xrealloc (stack_copy, (stack_copy_size = i)); |
| 1155 | if (stack_copy) | 1230 | if (stack_copy) |
| 1156 | { | 1231 | { |
| 1157 | if ((int) (&stack_top_variable - stack_bottom) > 0) | 1232 | if ((int) (&stack_top_variable - stack_bottom) > 0) |
| @@ -1804,7 +1879,7 @@ gc_sweep () | |||
| 1804 | else | 1879 | else |
| 1805 | all_buffers = buffer->next; | 1880 | all_buffers = buffer->next; |
| 1806 | next = buffer->next; | 1881 | next = buffer->next; |
| 1807 | free (buffer); | 1882 | xfree (buffer); |
| 1808 | buffer = next; | 1883 | buffer = next; |
| 1809 | } | 1884 | } |
| 1810 | else | 1885 | else |
| @@ -1845,7 +1920,7 @@ gc_sweep () | |||
| 1845 | else | 1920 | else |
| 1846 | all_vectors = vector->next; | 1921 | all_vectors = vector->next; |
| 1847 | next = vector->next; | 1922 | next = vector->next; |
| 1848 | free (vector); | 1923 | xfree (vector); |
| 1849 | vector = next; | 1924 | vector = next; |
| 1850 | } | 1925 | } |
| 1851 | else | 1926 | else |
| @@ -1868,7 +1943,7 @@ gc_sweep () | |||
| 1868 | else | 1943 | else |
| 1869 | large_string_blocks = sb->next; | 1944 | large_string_blocks = sb->next; |
| 1870 | next = sb->next; | 1945 | next = sb->next; |
| 1871 | free (sb); | 1946 | xfree (sb); |
| 1872 | sb = next; | 1947 | sb = next; |
| 1873 | } | 1948 | } |
| 1874 | else | 1949 | else |
| @@ -1983,7 +2058,7 @@ compact_strings () | |||
| 1983 | while (from_sb) | 2058 | while (from_sb) |
| 1984 | { | 2059 | { |
| 1985 | to_sb = from_sb->next; | 2060 | to_sb = from_sb->next; |
| 1986 | free (from_sb); | 2061 | xfree (from_sb); |
| 1987 | from_sb = to_sb; | 2062 | from_sb = to_sb; |
| 1988 | } | 2063 | } |
| 1989 | 2064 | ||
| @@ -1998,7 +2073,7 @@ compact_strings () | |||
| 1998 | { | 2073 | { |
| 1999 | if (from_sb->next = to_sb->next) | 2074 | if (from_sb->next = to_sb->next) |
| 2000 | from_sb->next->prev = from_sb; | 2075 | from_sb->next->prev = from_sb; |
| 2001 | free (to_sb); | 2076 | xfree (to_sb); |
| 2002 | } | 2077 | } |
| 2003 | else | 2078 | else |
| 2004 | from_sb = to_sb; | 2079 | from_sb = to_sb; |