+++ /dev/null
-
-/* This is a modified version of the file "arena.c" from
- "C Interfaces and Implementations", by David R. Hanson.
- The license is below.
-*/
-/*
-
-The author of this software is David R. Hanson.
-
-Copyright (c) 1994,1995,1996,1997 by David R. Hanson. All Rights Reserved.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose, subject to the provisions described below, without fee is
-hereby granted, provided that this entire notice is included in all
-copies of any software that is or includes a copy or modification of
-this software and in all copies of the supporting documentation for
-such software.
-
-THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTY. IN PARTICULAR, THE AUTHOR DOES MAKE ANY REPRESENTATION OR
-WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR
-ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-
-David Hanson / drh@microsoft.com / http://www.research.microsoft.com/~drh/
-$Id: CPYRIGHT,v 1.2 1997/11/04 22:31:40 drh Exp $
-*/
-
-
-//static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/arena.doc,v 1.10 1997/02/21 19:45:19 drh Exp $";
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "basictypes.h"
-
-//#include "assert.h"
-//#include "except.h"
-#include "arena.h"
-#define T Arena_T
-//const Except_T Arena_NewFailed =
-// { "Arena Creation Failed" };
-//const Except_T Arena_Failed =
-// { "Arena Allocation Failed" };
-#define THRESHOLD 10
-struct T {
- T prev;
- char *avail;
- char *limit;
-};
-union align {
-#ifdef MAXALIGN
- char pad[MAXALIGN];
-#else
- int i;
- long l;
- long *lp;
- void *p;
- void (*fp)(void);
- float f;
- double d;
- long double ld;
-#endif
-};
-union header {
- struct T b;
- union align a;
-};
-static T freechunks;
-static int nfree;
-T Arena_new(void) {
- T arena = malloc(sizeof (*arena));
- if (arena == NULL)
- panic("Arena_NewFailed");
- arena->prev = NULL;
- arena->limit = arena->avail = NULL;
- return arena;
-}
-void Arena_dispose(T *ap) {
- assert(ap && *ap);
- Arena_free(*ap);
- free(*ap);
- *ap = NULL;
-}
-void *Arena_alloc(T arena, long nbytes,
- const char *file, int line) {
- assert(arena);
- assert(nbytes > 0);
- nbytes = ((nbytes + sizeof (union align) - 1)/
- (sizeof (union align)))*(sizeof (union align));
- while (nbytes > arena->limit - arena->avail) {
- T ptr;
- char *limit;
- if ((ptr = freechunks) != NULL) {
- freechunks = freechunks->prev;
- nfree--;
- limit = ptr->limit;
- } else {
- long m = sizeof (union header) + nbytes + 10*1024;
- ptr = malloc(m);
- if (ptr == NULL)
- {
- if (file == NULL)
- panic("Arena_Failed");
- else
- {
- fprintf(stderr, "\nArena_alloc: allocation failed at %s:%d\n", file, line);
- panic("Arena_alloc: allocation failed");
- //Except_raise(&Arena_Failed, file, line);
- }
- }
- limit = (char *)ptr + m;
- }
- *ptr = *arena;
- arena->avail = (char *)((union header *)ptr + 1);
- arena->limit = limit;
- arena->prev = ptr;
- }
- arena->avail += nbytes;
- return arena->avail - nbytes;
-}
-void *Arena_calloc(T arena, long count, long nbytes,
- const char *file, int line) {
- void *ptr;
- assert(count > 0);
- ptr = Arena_alloc(arena, count*nbytes, file, line);
- memset(ptr, '\0', count*nbytes);
- return ptr;
-}
-void Arena_free(T arena) {
- assert(arena);
- while (arena->prev) {
- struct T tmp = *arena->prev;
- if (nfree < THRESHOLD) {
- arena->prev->prev = freechunks;
- freechunks = arena->prev;
- nfree++;
- freechunks->limit = arena->limit;
- } else
- free(arena->prev);
- *arena = tmp;
- }
- assert(arena->limit == NULL);
- assert(arena->avail == NULL);
-}