Back to index

tetex-bin  3.0
Classes | Defines | Typedefs | Functions | Variables
alloca.c File Reference
#include <alloca.h>
#include <string.h>
#include <stdlib.h>

Go to the source code of this file.

Classes

union  hdr
struct  hdr.h

Defines

#define memory_full()   abort ()
#define ADDRESS_FUNCTION(arg)   &(arg)
#define STACK_DIRECTION   0 /* Direction unknown. */
#define STACK_DIR   stack_dir
#define ALIGN_SIZE   sizeof(double)

Typedefs

typedef union hdr header

Functions

static void find_stack_direction (void)
voidalloca (size_t size)

Variables

static int stack_dir
static headerlast_alloca_header = NULL

Class Documentation

union hdr

Definition at line 151 of file alloca.c.

Class Members
char align
struct hdr h
struct hdr h
struct hdr.h

Definition at line 136 of file alloca.c.

Class Members
char * deep
union hdr * next

Define Documentation

#define ADDRESS_FUNCTION (   arg)    &(arg)

Definition at line 74 of file alloca.c.

#define ALIGN_SIZE   sizeof(double)

Definition at line 130 of file alloca.c.

#define memory_full ( )    abort ()

Definition at line 41 of file alloca.c.

#define STACK_DIR   stack_dir

Definition at line 96 of file alloca.c.

#define STACK_DIRECTION   0 /* Direction unknown. */

Definition at line 86 of file alloca.c.


Typedef Documentation

typedef union hdr header

Function Documentation

void* alloca ( size_t  size)

Definition at line 153 of file alloca.c.

{
  auto char probe;          /* Probes stack depth: */
  register char *depth = ADDRESS_FUNCTION (probe);

#  if STACK_DIRECTION == 0
  if (STACK_DIR == 0)              /* Unknown growth direction.  */
    find_stack_direction ();
#  endif

  /* Reclaim garbage, defined as all alloca'd storage that
     was allocated from deeper in the stack than currently.  */

  {
    register header *hp;    /* Traverses linked list.  */

#  ifdef emacs
    BLOCK_INPUT;
#  endif

    for (hp = last_alloca_header; hp != NULL;)
      if ((STACK_DIR > 0 && hp->h.deep > depth)
         || (STACK_DIR < 0 && hp->h.deep < depth))
       {
         register header *np = hp->h.next;

         free (hp);         /* Collect garbage.  */

         hp = np;           /* -> next header.  */
       }
      else
       break;               /* Rest are not deeper.  */

    last_alloca_header = hp;       /* -> last valid storage.  */

#  ifdef emacs
    UNBLOCK_INPUT;
#  endif
  }

  if (size == 0)
    return NULL;            /* No allocation required.  */

  /* Allocate combined header + user data storage.  */

  {
    /* Address of header.  */
    register header *new;

    size_t combined_size = sizeof (header) + size;
    if (combined_size < sizeof (header))
      memory_full ();

    new = malloc (combined_size);

    if (! new)
      memory_full ();

    new->h.next = last_alloca_header;
    new->h.deep = depth;

    last_alloca_header = new;

    /* User storage begins just after header.  */

    return (void *) (new + 1);
  }
}

Here is the call graph for this function:

static void find_stack_direction ( void  ) [static]

Definition at line 99 of file alloca.c.

{
  static char *addr = NULL; /* Address of first `dummy', once known.  */
  auto char dummy;          /* To get stack address.  */

  if (addr == NULL)
    {                       /* Initial entry.  */
      addr = ADDRESS_FUNCTION (dummy);

      find_stack_direction ();     /* Recurse once.  */
    }
  else
    {
      /* Second entry.  */
      if (ADDRESS_FUNCTION (dummy) > addr)
       stack_dir = 1;              /* Stack grew upward.  */
      else
       stack_dir = -1;             /* Stack grew downward.  */
    }
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 143 of file alloca.c.

int stack_dir [static]

Definition at line 95 of file alloca.c.