~drizzle-trunk/drizzle/development

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