comparison src/alloc.c @ 2439:b6c62e4abf59

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.
author Jim Blandy <jimb@redhat.com>
date Wed, 31 Mar 1993 10:55:33 +0000
parents 4817a2197ac2
children 7ba4316ae840
comparison
equal deleted inserted replaced
2438:b513de4de386 2439:b6c62e4abf59
24 #include "puresize.h" 24 #include "puresize.h"
25 #ifndef standalone 25 #ifndef standalone
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"
32 33
33 #define max(A,B) ((A) > (B) ? (A) : (B)) 34 #define max(A,B) ((A) > (B) ? (A) : (B))
41 { \ 42 { \
42 Lisp_Object val; \ 43 Lisp_Object val; \
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)
50 51
51 /* Number of bytes of consing done since the last gc */ 52 /* Number of bytes of consing done since the last gc */
147 memory_full () 148 memory_full ()
148 { 149 {
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)
156 int size; 157 int 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;
164 } 167 }
165 168
168 long *block; 171 long *block;
169 int size; 172 int 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
186 #ifdef USE_TEXT_PROPERTIES 272 #ifdef USE_TEXT_PROPERTIES
187 #define INTERVAL_BLOCK_SIZE \ 273 #define INTERVAL_BLOCK_SIZE \
224 else 310 else
225 { 311 {
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;
236 interval_block = newi; 319 interval_block = newi;
237 interval_block_index = 0; 320 interval_block_index = 0;
350 } 433 }
351 else 434 else
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;
360 float_block_index = 0; 442 float_block_index = 0;
361 } 443 }
425 } 507 }
426 else 508 else
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;
435 cons_block_index = 0; 516 cons_block_index = 0;
436 } 517 }
496 577
497 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) 578 if (XTYPE (length) != Lisp_Int || XINT (length) < 0)
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);
507 consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object); 586 consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object);
508 587
615 } 694 }
616 else 695 else
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;
625 symbol_block_index = 0; 703 symbol_block_index = 0;
626 } 704 }
678 } 756 }
679 else 757 else
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;
688 marker_block_index = 0; 765 marker_block_index = 0;
689 } 766 }
828 } 905 }
829 else if (fullsize > STRING_BLOCK_OUTSIZE) 906 else if (fullsize > STRING_BLOCK_OUTSIZE)
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;
839 large_string_blocks = new; 915 large_string_blocks = new;
840 XSET (val, Lisp_String, 916 XSET (val, Lisp_String,
842 } 918 }
843 else 919 else
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;
852 new->prev = current_string_block; 927 new->prev = current_string_block;
853 new->next = 0; 928 new->next = 0;
1147 i = &stack_top_variable - stack_bottom; 1222 i = &stack_top_variable - stack_bottom;
1148 if (i < 0) i = -i; 1223 if (i < 0) i = -i;
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)
1158 bcopy (stack_bottom, stack_copy, i); 1233 bcopy (stack_bottom, stack_copy, i);
1159 else 1234 else
1802 if (prev) 1877 if (prev)
1803 prev->next = buffer->next; 1878 prev->next = buffer->next;
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
1811 { 1886 {
1812 XUNMARK (buffer->name); 1887 XUNMARK (buffer->name);
1843 if (prev) 1918 if (prev)
1844 prev->next = vector->next; 1919 prev->next = vector->next;
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
1852 { 1927 {
1853 vector->size &= ~ARRAY_MARK_FLAG; 1928 vector->size &= ~ARRAY_MARK_FLAG;
1866 if (prev) 1941 if (prev)
1867 prev->next = sb->next; 1942 prev->next = sb->next;
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
1875 { 1950 {
1876 ((struct Lisp_String *)(&sb->chars[0]))->size 1951 ((struct Lisp_String *)(&sb->chars[0]))->size
1981 from_sb = to_sb->next; 2056 from_sb = to_sb->next;
1982 to_sb->next = 0; 2057 to_sb->next = 0;
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
1990 /* Free any empty string blocks further back in the chain. 2065 /* Free any empty string blocks further back in the chain.
1991 This loop will never free first_string_block, but it is very 2066 This loop will never free first_string_block, but it is very
1996 { 2071 {
1997 if (to_sb->pos == 0) 2072 if (to_sb->pos == 0)
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;
2005 } 2080 }
2006 } 2081 }