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