chiark / gitweb /
Fix for Cygwin.
[mLib] / sub.c
diff --git a/sub.c b/sub.c
index 45dcac46a5606af1aee313275c35704b39ad5315..a0d49818f241454932b5bfd54c5476ede11aa814 100644 (file)
--- a/sub.c
+++ b/sub.c
@@ -1,6 +1,6 @@
 /* -*-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
@@ -83,6 +60,7 @@
 
 /* --- 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];
@@ -101,6 +83,16 @@ 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@ --- *
@@ -116,11 +108,15 @@ subarena sub_global;
 
 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;
 }
 
@@ -136,6 +132,19 @@ void subarena_create(subarena *s, arena *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];
@@ -144,7 +153,10 @@ void subarena_destroy(subarena *s)
       p = *(void **)q;
       A_FREE(s->a, q);
     }
+    s->bin[i] = 0;
   }
+
+#endif
 }
 
 /* --- @subarena_alloc@ --- *
@@ -161,6 +173,28 @@ void subarena_destroy(subarena *s)
 
 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;
 
@@ -168,10 +202,10 @@ void *subarena_alloc(subarena *s, size_t sz)
 
   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)
@@ -207,6 +241,8 @@ void *subarena_alloc(subarena *s, size_t sz)
   p = s->bin[bin];
   s->bin[bin] = *(void **)p;
   return (p);
+
+#endif
 }
 
 /* --- @subarena_free@ --- *
@@ -222,6 +258,22 @@ void *subarena_alloc(subarena *s, size_t sz)
 
 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)
@@ -230,6 +282,8 @@ void subarena_free(subarena *s, void *p, size_t sz)
     *(void **)p = s->bin[bin];
     s->bin[bin] = p;
   }
+
+#endif
 }
 
 /*----- Compatibility stuff -----------------------------------------------*/
@@ -268,6 +322,7 @@ void (sub_free)(void *p, size_t sz) { sub_free(p, sz); }
 
 void sub_init(void)
 {
+#ifndef SUBARENA_TRIVIAL
   int i;
 
   /* --- Initialize the sizes bins --- */
@@ -276,6 +331,7 @@ void sub_init(void)
     sizes[i] = ((SUB_CHUNK + SUB_BINSZ(i) - 1) /
                     SUB_BINSZ(i) * SUB_BINSZ(i));
   }
+#endif
 }
 
 /*----- Debugging code ----------------------------------------------------*/