#include <stdlib.h>
#include "global.h"

#ifdef DEBUG
#define FREED	0x8000
#endif

@0

typedef struct BlockOf_@1 {
  struct BlockOf_@1 *next;
  @1 block[@2];
} BlockOf_@1;

static struct {
  BlockOf_@1 *blocklist;
  @1 *freelist;
#ifdef DEBUG
  int num_blocks;
#endif
} Arena_@1 = {0, 0
#ifdef DEBUG
		  , 0
#endif
		     };

static void getblock_@1()
{
  register BlockOf_@1 *B =
	(BlockOf_@1 *)mallok(sizeof (BlockOf_@1));
  register int i;

  for (i = 0; i < @2 - 1; i++) {
    B->block[i].next = &(B->block[i + 1]);
#ifdef DEBUG
    B->block[i].flags = FREED;
#endif
  }
  B->block[@2 - 1].next = Arena_@1.freelist;
#ifdef DEBUG
  B->block[@2 - 1].flags = FREED;
#endif
  Arena_@1.freelist = B->block;
  B->next = Arena_@1.blocklist;
  Arena_@1.blocklist = B;
#ifdef DEBUG
  Arena_@1.num_blocks++;
#endif
}

@1 *alloc_@1()
{
  register @1 *T = Arena_@1.freelist;

  if (!T) {getblock_@1(); T = Arena_@1.freelist;}
  Arena_@1.freelist = T->next; T->next = 0;
#ifdef DEBUG
  T->flags &= ~FREED;
#endif
  return T;
}

void dealloc_@1(T) register @1 *T;
{
  T->next = Arena_@1.freelist;
  Arena_@1.freelist = T;
#ifdef DEBUG
  T->flags |= FREED;
#endif
}

void cleanup_@1()
{
  register BlockOf_@1 *B1, *B2;

  for (B1 = Arena_@1.blocklist; B1; B1 = B2) {
#ifdef DEBUG
    register int i, n = 0;

    for (i = 0; i < @2; i++) {
      if (!(B1->block[i].flags & FREED))
	n++;
    }
    fprintf(stderr, "%d @1 blocks allocated\n", Arena_@1.num_blocks);
    if (n > 0)
      bugchk("%s @1 struct(s) leaked", n);
#endif
    B2 = B1->next;
    free(B1);
  }
}
