* Set development version to 2.3.29
[fvwm.git] / libs / alloca.c
blob5f14b93d2173b13cf0e353d478b490034e0ae60c
1 /* This program is free software; you can redistribute it and/or modify
2 * it under the terms of the GNU General Public License as published by
3 * the Free Software Foundation; either version 2 of the License, or
4 * (at your option) any later version.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 /* alloca.c -- allocate automatically reclaimed memory
17 (Mostly) portable public-domain implementation -- D A Gwyn
19 This implementation of the PWB library alloca function,
20 which is used to allocate space off the run-time stack so
21 that it is automatically reclaimed upon procedure exit,
22 was inspired by discussions with J. Q. Johnson of Cornell.
23 J.Otto Tennant <jot@cray.com> contributed the Cray support.
25 There are some preprocessor constants that can
26 be defined when compiling for your specific system, for
27 improved efficiency; however, the defaults should be okay.
29 The general concept of this implementation is to keep
30 track of all alloca-allocated blocks, and reclaim any
31 that are found to be deeper in the stack than the current
32 invocation. This heuristic does not reclaim storage as
33 soon as it becomes invalid, but it will do so eventually.
35 As a special case, alloca(0) reclaims storage without
36 allocating any. It is a good idea to use alloca(0) in
37 your main control loop, etc. to force garbage collection. */
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
43 #ifdef HAVE_STRING_H
44 #include <string.h>
45 #endif
46 #ifdef HAVE_STDLIB_H
47 #include <stdlib.h>
48 #endif
50 #ifdef emacs
51 #include "blockinput.h"
52 #endif
54 /* If compiling with GCC 2, this file's not needed. */
55 #if !defined (__GNUC__) || __GNUC__ < 2
57 /* If someone has defined alloca as a macro,
58 there must be some other way alloca is supposed to work. */
59 #ifndef alloca
61 #ifdef emacs
62 #ifdef static
63 /* actually, only want this if static is defined as ""
64 -- this is for usg, in which emacs must undefine static
65 in order to make unexec workable
67 #ifndef STACK_DIRECTION
68 you
69 lose
70 -- must know STACK_DIRECTION at compile-time
71 #endif /* STACK_DIRECTION undefined */
72 #endif /* static */
73 #endif /* emacs */
75 /* If your stack is a linked list of frames, you have to
76 provide an "address metric" ADDRESS_FUNCTION macro. */
78 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
79 long i00afunc ();
80 #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
81 #else
82 #define ADDRESS_FUNCTION(arg) &(arg)
83 #endif
85 #if __STDC__
86 typedef void *pointer;
87 #else
88 typedef char *pointer;
89 #endif
91 #ifndef NULL
92 #define NULL 0
93 #endif
95 /* Different portions of Emacs need to call different versions of
96 malloc. The Emacs executable needs alloca to call xmalloc, because
97 ordinary malloc isn't protected from input signals. On the other
98 hand, the utilities in lib-src need alloca to call malloc; some of
99 them are very simple, and don't have an xmalloc routine.
101 Non-Emacs programs expect this to call use xmalloc.
103 Callers below should use malloc. */
105 #ifndef emacs
106 #define malloc xmalloc
107 #endif
108 extern pointer malloc ();
110 /* Define STACK_DIRECTION if you know the direction of stack
111 growth for your system; otherwise it will be automatically
112 deduced at run-time.
114 STACK_DIRECTION > 0 => grows toward higher addresses
115 STACK_DIRECTION < 0 => grows toward lower addresses
116 STACK_DIRECTION = 0 => direction of growth unknown */
118 #ifndef STACK_DIRECTION
119 #define STACK_DIRECTION 0 /* Direction unknown. */
120 #endif
122 #if STACK_DIRECTION != 0
124 #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
126 #else /* STACK_DIRECTION == 0; need run-time code. */
128 static int stack_dir; /* 1 or -1 once known. */
129 #define STACK_DIR stack_dir
131 static void
132 find_stack_direction ()
134 static char *addr = NULL; /* Address of first `dummy', once known. */
135 auto char dummy; /* To get stack address. */
137 if (addr == NULL)
138 { /* Initial entry. */
139 addr = ADDRESS_FUNCTION (dummy);
141 find_stack_direction (); /* Recurse once. */
143 else
145 /* Second entry. */
146 if (ADDRESS_FUNCTION (dummy) > addr)
147 stack_dir = 1; /* Stack grew upward. */
148 else
149 stack_dir = -1; /* Stack grew downward. */
153 #endif /* STACK_DIRECTION == 0 */
155 /* An "alloca header" is used to:
156 (a) chain together all alloca'ed blocks;
157 (b) keep track of stack depth.
159 It is very important that sizeof(header) agree with malloc
160 alignment chunk size. The following default should work okay. */
162 #ifndef ALIGN_SIZE
163 #define ALIGN_SIZE sizeof(double)
164 #endif
166 typedef union hdr
168 char align[ALIGN_SIZE]; /* To force sizeof(header). */
169 struct
171 union hdr *next; /* For chaining headers. */
172 char *deep; /* For stack depth measure. */
173 } h;
174 } header;
176 static header *last_alloca_header = NULL; /* -> last alloca header. */
178 /* Return a pointer to at least SIZE bytes of storage,
179 which will be automatically reclaimed upon exit from
180 the procedure that called alloca. Originally, this space
181 was supposed to be taken from the current stack frame of the
182 caller, but that method cannot be made to work for some
183 implementations of C, for example under Gould's UTX/32. */
185 pointer
186 alloca (size)
187 unsigned size;
189 auto char probe; /* Probes stack depth: */
190 register char *depth = ADDRESS_FUNCTION (probe);
192 #if STACK_DIRECTION == 0
193 if (STACK_DIR == 0) /* Unknown growth direction. */
194 find_stack_direction ();
195 #endif
197 /* Reclaim garbage, defined as all alloca'd storage that
198 was allocated from deeper in the stack than currently. */
201 register header *hp; /* Traverses linked list. */
203 #ifdef emacs
204 BLOCK_INPUT;
205 #endif
207 for (hp = last_alloca_header; hp != NULL;)
208 if ((STACK_DIR > 0 && hp->h.deep > depth)
209 || (STACK_DIR < 0 && hp->h.deep < depth))
211 register header *np = hp->h.next;
213 free ((pointer) hp); /* Collect garbage. */
215 hp = np; /* -> next header. */
217 else
218 break; /* Rest are not deeper. */
220 last_alloca_header = hp; /* -> last valid storage. */
222 #ifdef emacs
223 UNBLOCK_INPUT;
224 #endif
227 if (size == 0)
228 return NULL; /* No allocation required. */
230 /* Allocate combined header + user data storage. */
233 register pointer new = malloc (sizeof (header) + size);
234 /* Address of header. */
236 if (new == 0)
237 abort();
239 ((header *) new)->h.next = last_alloca_header;
240 ((header *) new)->h.deep = depth;
242 last_alloca_header = (header *) new;
244 /* User storage begins just after header. */
246 return (pointer) ((char *) new + sizeof (header));
250 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
252 #ifdef DEBUG_I00AFUNC
253 #include <stdio.h>
254 #endif
256 #ifndef CRAY_STACK
257 #define CRAY_STACK
258 #ifndef CRAY2
259 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
260 struct stack_control_header
262 long shgrow:32; /* Number of times stack has grown. */
263 long shaseg:32; /* Size of increments to stack. */
264 long shhwm:32; /* High water mark of stack. */
265 long shsize:32; /* Current size of stack (all segments). */
268 /* The stack segment linkage control information occurs at
269 the high-address end of a stack segment. (The stack
270 grows from low addresses to high addresses.) The initial
271 part of the stack segment linkage control information is
272 0200 (octal) words. This provides for register storage
273 for the routine which overflows the stack. */
275 struct stack_segment_linkage
277 long ss[0200]; /* 0200 overflow words. */
278 long sssize:32; /* Number of words in this segment. */
279 long ssbase:32; /* Offset to stack base. */
280 long:32;
281 long sspseg:32; /* Offset to linkage control of previous
282 segment of stack. */
283 long:32;
284 long sstcpt:32; /* Pointer to task common address block. */
285 long sscsnm; /* Private control structure number for
286 microtasking. */
287 long ssusr1; /* Reserved for user. */
288 long ssusr2; /* Reserved for user. */
289 long sstpid; /* Process ID for pid based multi-tasking. */
290 long ssgvup; /* Pointer to multitasking thread giveup. */
291 long sscray[7]; /* Reserved for Cray Research. */
292 long ssa0;
293 long ssa1;
294 long ssa2;
295 long ssa3;
296 long ssa4;
297 long ssa5;
298 long ssa6;
299 long ssa7;
300 long sss0;
301 long sss1;
302 long sss2;
303 long sss3;
304 long sss4;
305 long sss5;
306 long sss6;
307 long sss7;
310 #else /* CRAY2 */
311 /* The following structure defines the vector of words
312 returned by the STKSTAT library routine. */
313 struct stk_stat
315 long now; /* Current total stack size. */
316 long maxc; /* Amount of contiguous space which would
317 be required to satisfy the maximum
318 stack demand to date. */
319 long high_water; /* Stack high-water mark. */
320 long overflows; /* Number of stack overflow ($STKOFEN) calls. */
321 long hits; /* Number of internal buffer hits. */
322 long extends; /* Number of block extensions. */
323 long stko_mallocs; /* Block allocations by $STKOFEN. */
324 long underflows; /* Number of stack underflow calls ($STKRETN). */
325 long stko_free; /* Number of deallocations by $STKRETN. */
326 long stkm_free; /* Number of deallocations by $STKMRET. */
327 long segments; /* Current number of stack segments. */
328 long maxs; /* Maximum number of stack segments so far. */
329 long pad_size; /* Stack pad size. */
330 long current_address; /* Current stack segment address. */
331 long current_size; /* Current stack segment size. This
332 number is actually corrupted by STKSTAT to
333 include the fifteen word trailer area. */
334 long initial_address; /* Address of initial segment. */
335 long initial_size; /* Size of initial segment. */
338 /* The following structure describes the data structure which trails
339 any stack segment. I think that the description in 'asdef' is
340 out of date. I only describe the parts that I am sure about. */
342 struct stk_trailer
344 long this_address; /* Address of this block. */
345 long this_size; /* Size of this block (does not include
346 this trailer). */
347 long unknown2;
348 long unknown3;
349 long link; /* Address of trailer block of previous
350 segment. */
351 long unknown5;
352 long unknown6;
353 long unknown7;
354 long unknown8;
355 long unknown9;
356 long unknown10;
357 long unknown11;
358 long unknown12;
359 long unknown13;
360 long unknown14;
363 #endif /* CRAY2 */
364 #endif /* not CRAY_STACK */
366 #ifdef CRAY2
367 /* Determine a "stack measure" for an arbitrary ADDRESS.
368 I doubt that "lint" will like this much. */
370 static long
371 i00afunc (long *address)
373 struct stk_stat status;
374 struct stk_trailer *trailer;
375 long *block, size;
376 long result = 0;
378 /* We want to iterate through all of the segments. The first
379 step is to get the stack status structure. We could do this
380 more quickly and more directly, perhaps, by referencing the
381 $LM00 common block, but I know that this works. */
383 STKSTAT (&status);
385 /* Set up the iteration. */
387 trailer = (struct stk_trailer *) (status.current_address
388 + status.current_size
389 - 15);
391 /* There must be at least one stack segment. Therefore it is
392 a fatal error if "trailer" is null. */
394 if (trailer == 0)
395 abort ();
397 /* Discard segments that do not contain our argument address. */
399 while (trailer != 0)
401 block = (long *) trailer->this_address;
402 size = trailer->this_size;
403 if (block == 0 || size == 0)
404 abort ();
405 trailer = (struct stk_trailer *) trailer->link;
406 if ((block <= address) && (address < (block + size)))
407 break;
410 /* Set the result to the offset in this segment and add the sizes
411 of all predecessor segments. */
413 result = address - block;
415 if (trailer == 0)
417 return result;
422 if (trailer->this_size <= 0)
423 abort ();
424 result += trailer->this_size;
425 trailer = (struct stk_trailer *) trailer->link;
427 while (trailer != 0);
429 /* We are done. Note that if you present a bogus address (one
430 not in any segment), you will get a different number back, formed
431 from subtracting the address of the first block. This is probably
432 not what you want. */
434 return (result);
437 #else /* not CRAY2 */
438 /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
439 Determine the number of the cell within the stack,
440 given the address of the cell. The purpose of this
441 routine is to linearize, in some sense, stack addresses
442 for alloca. */
444 static long
445 i00afunc (long address)
447 long stkl = 0;
449 long size, pseg, this_segment, stack;
450 long result = 0;
452 struct stack_segment_linkage *ssptr;
454 /* Register B67 contains the address of the end of the
455 current stack segment. If you (as a subprogram) store
456 your registers on the stack and find that you are past
457 the contents of B67, you have overflowed the segment.
459 B67 also points to the stack segment linkage control
460 area, which is what we are really interested in. */
462 stkl = CRAY_STACKSEG_END ();
463 ssptr = (struct stack_segment_linkage *) stkl;
465 /* If one subtracts 'size' from the end of the segment,
466 one has the address of the first word of the segment.
468 If this is not the first segment, 'pseg' will be
469 nonzero. */
471 pseg = ssptr->sspseg;
472 size = ssptr->sssize;
474 this_segment = stkl - size;
476 /* It is possible that calling this routine itself caused
477 a stack overflow. Discard stack segments which do not
478 contain the target address. */
480 while (!(this_segment <= address && address <= stkl))
482 #ifdef DEBUG_I00AFUNC
483 fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
484 #endif
485 if (pseg == 0)
486 break;
487 stkl = stkl - pseg;
488 ssptr = (struct stack_segment_linkage *) stkl;
489 size = ssptr->sssize;
490 pseg = ssptr->sspseg;
491 this_segment = stkl - size;
494 result = address - this_segment;
496 /* If you subtract pseg from the current end of the stack,
497 you get the address of the previous stack segment's end.
498 This seems a little convoluted to me, but I'll bet you save
499 a cycle somewhere. */
501 while (pseg != 0)
503 #ifdef DEBUG_I00AFUNC
504 fprintf (stderr, "%011o %011o\n", pseg, size);
505 #endif
506 stkl = stkl - pseg;
507 ssptr = (struct stack_segment_linkage *) stkl;
508 size = ssptr->sssize;
509 pseg = ssptr->sspseg;
510 result += size;
512 return (result);
515 #endif /* not CRAY2 */
516 #endif /* CRAY */
518 #endif /* no alloca */
519 #endif /* not GCC version 2 */