/* -*-c-*-
*
- * $Id: sub.c,v 1.6 2000/06/17 10:35:51 mdw Exp $
+ * $Id: sub.c,v 1.9 2004/04/08 01:36:13 mdw Exp $
*
* Allocation of known-size blocks
*
* MA 02111-1307, USA.
*/
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: sub.c,v $
- * Revision 1.6 2000/06/17 10:35:51 mdw
- * Major overhaul for arena support.
- *
- * Revision 1.5 1999/05/19 20:27:11 mdw
- * Change naming to match newer mLib conventions.
- *
- * Revision 1.4 1999/05/13 22:48:55 mdw
- * Change `-ise' to `-ize' throughout.
- *
- * Revision 1.3 1999/05/06 19:51:35 mdw
- * Reformatted the LGPL notice a little bit.
- *
- * Revision 1.2 1999/05/05 18:50:31 mdw
- * Change licensing conditions to LGPL.
- *
- * Revision 1.1.1.1 1998/06/17 23:44:42 mdw
- * Initial version of mLib
- *
- */
-
/*----- The big idea ------------------------------------------------------*
*
* This file provides an extra layer over @malloc@. It provides fast
/* --- ANSI headers --- */
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "exc.h"
#include "sub.h"
+/*----- Configuration tweaks ----------------------------------------------*/
+
+/* #define SUBARENA_TRIVIAL */
+
/*----- Static variables --------------------------------------------------*/
static size_t sizes[SUB_BINS];
subarena sub_global;
+#ifdef SUBARENA_TRIVIAL
+
+typedef struct sub_link {
+ struct sub_link *next;
+ void *p;
+ size_t sz;
+} sub_link;
+
+#endif
+
/*----- Main code ---------------------------------------------------------*/
/* --- @subarena_create@ --- *
void subarena_create(subarena *s, arena *a)
{
+#ifdef SUBARENA_TRIVIAL
+ s->bin[0] = 0;
+#else
size_t i;
if (!sizes[1])
sub_init();
for (i = 0; i < SUB_BINS; i++)
s->bin[i] = 0;
+#endif
s->a = a;
}
void subarena_destroy(subarena *s)
{
+#ifdef SUBARENA_TRIVIAL
+
+ sub_link *l, *ll;
+
+ for (l = s->bin[0]; l; l = ll) {
+ ll = l;
+ a_free(s->a, l->p);
+ a_free(s->a, l);
+ }
+ s->bin[0] = 0;
+
+#else
+
size_t i;
for (i = 0; i < SUB_BINS; i++) {
void *p = s->bin[i];
p = *(void **)q;
A_FREE(s->a, q);
}
+ s->bin[i] = 0;
}
+
+#endif
}
/* --- @subarena_alloc@ --- *
void *subarena_alloc(subarena *s, size_t sz)
{
+#ifdef SUBARENA_TRIVIAL
+
+ sub_link *l;
+ void *p;
+
+ if (!s->a)
+ subarena_create(s, arena_global);
+
+ if ((l = a_alloc(s->a, sizeof(*l))) == 0)
+ return (0);
+ if ((p = a_alloc(s->a, sz)) == 0) {
+ a_free(s->a, l);
+ return (0);
+ }
+ l->p = p;
+ l->sz = sz;
+ l->next = s->bin[0];
+ s->bin[0] = l;
+ return (p);
+
+#else
+
int bin;
void *p;
if (!s->a)
subarena_create(s, arena_global);
- bin = SUB_BIN(sz);
/* --- Handle oversize blocks --- */
+ bin = SUB_BIN(sz);
if (bin >= SUB_BINS) {
void *p = A_ALLOC(s->a, sz);
if (!p)
p = s->bin[bin];
s->bin[bin] = *(void **)p;
return (p);
+
+#endif
}
/* --- @subarena_free@ --- *
void subarena_free(subarena *s, void *p, size_t sz)
{
+#ifdef SUBARENA_TRIVIAL
+
+ sub_link *lh = s->bin[0], **l, *ll;
+
+ for (l = &lh; *l && (*l)->p != p; l = &(*l)->next)
+ ;
+ ll = *l;
+ assert(ll);
+ assert(ll->sz == sz);
+ *l = ll->next;
+ a_free(s->a, ll);
+ a_free(s->a, p);
+ s->bin[0] = lh;
+
+#else
+
int bin = SUB_BIN(sz);
if (bin >= SUB_BINS)
*(void **)p = s->bin[bin];
s->bin[bin] = p;
}
+
+#endif
}
/*----- Compatibility stuff -----------------------------------------------*/
void sub_init(void)
{
+#ifndef SUBARENA_TRIVIAL
int i;
/* --- Initialize the sizes bins --- */
sizes[i] = ((SUB_CHUNK + SUB_BINSZ(i) - 1) /
SUB_BINSZ(i) * SUB_BINSZ(i));
}
+#endif
}
/*----- Debugging code ----------------------------------------------------*/