]> mj.ucw.cz Git - libucw.git/commitdiff
Resources: Implemented subpools
authorMartin Mares <mj@ucw.cz>
Sun, 17 Apr 2011 15:21:53 +0000 (17:21 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 17 Apr 2011 15:21:53 +0000 (17:21 +0200)
I also had to extend the pool/resource dumping functions, so that
they can print complex structures. All functions pass the amount
of indent to apply and the resource->dump callback is expected
to include a `\n' after its output.

ucw/Makefile
ucw/fastbuf.c
ucw/res-fd.c
ucw/res-mem.c
ucw/res-subpool.c [new file with mode: 0644]
ucw/respool.c
ucw/respool.h
ucw/trans.c

index 6f076ed7da18032d2a2677aa9f2387d36d3d0f9b..8d7877119810f7001f94d7c41e33fa933e5a031d 100644 (file)
@@ -34,7 +34,7 @@ LIBUCW_MODS= \
        bbuf gary \
        getopt \
        strtonum \
-       respool trans res-fd res-mem
+       respool trans res-fd res-mem res-subpool
 
 LIBUCW_MAIN_INCLUDES= \
        lib.h log.h threads.h \
index 83c3b0790a60a8915d18ecfaed6e23ae8c282687..4068aab89adef2e30868530da34ea70686d5e1b5 100644 (file)
@@ -301,10 +301,10 @@ static void fb_res_free(struct resource *r)
   bclose(f);
 }
 
-static void fb_res_dump(struct resource *r)
+static void fb_res_dump(struct resource *r, uns indent UNUSED)
 {
   struct fastbuf *f = r->priv;
-  printf(" name=%s", f->name);
+  printf(" name=%s\n", f->name);
 }
 
 static const struct res_class fb_res_class = {
index 44ce4a3639e26cec659cd560503111d4f2236e04..ab04b8e7c151e9db0e7c957c9488e88bfeb95364 100644 (file)
@@ -20,9 +20,9 @@ fd_res_free(struct resource *r)
 }
 
 static void
-fd_res_dump(struct resource *r)
+fd_res_dump(struct resource *r, uns indent UNUSED)
 {
-  printf(" fd=%d", (int)(intptr_t) r->priv);
+  printf(" fd=%d\n", (int)(intptr_t) r->priv);
 }
 
 static const struct res_class fd_res_class = {
@@ -44,7 +44,7 @@ int main(void)
   struct respool *rp = rp_new("test", NULL);
   rp_switch(rp);
   res_for_fd(1);
-  rp_dump(rp);
+  rp_dump(rp, 0);
   rp_delete(rp);
   return 0;
 }
index b65b91697ae0efd19ab31880c174c9351ed14caa..10cb1d4b33f5ad02e79399c21e953a1eeecfb5f2 100644 (file)
@@ -26,10 +26,10 @@ mem_res_free(struct resource *r)
 }
 
 static void
-mem_res_dump(struct resource *r)
+mem_res_dump(struct resource *r, uns indent UNUSED)
 {
   struct res_mem *rm = (struct res_mem *) r;
-  printf(" size=%zu", rm->size);
+  printf(" size=%zu, ptr=%p\n", rm->size, r->priv);
 }
 
 static const struct res_class mem_res_class = {
@@ -77,10 +77,10 @@ int main(void)
   struct resource *r;
   char *p = res_malloc(3, &r);
   p[0] = p[1] = p[2] = 1;
-  rp_dump(rp);
+  rp_dump(rp, 0);
   p = res_realloc(r, 5);
   p[3] = p[4] = 2;
-  rp_dump(rp);
+  rp_dump(rp, 0);
   rp_delete(rp);
   return 0;
 }
diff --git a/ucw/res-subpool.c b/ucw/res-subpool.c
new file mode 100644 (file)
index 0000000..5b42713
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *     The UCW Library -- Resources for Sub-pools
+ *
+ *     (c) 2011 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include "ucw/lib.h"
+#include "ucw/respool.h"
+
+#include <stdio.h>
+
+static void
+subpool_res_free(struct resource *r)
+{
+  struct respool *rp = r->priv;
+  rp->subpool_of = NULL;
+  rp_delete(rp);
+}
+
+static void
+subpool_res_detach(struct resource *r)
+{
+  struct respool *rp = r->priv;
+  rp->subpool_of = NULL;
+}
+
+static void
+subpool_res_dump(struct resource *r, uns indent)
+{
+  printf(":\n");
+  rp_dump(r->priv, indent);
+}
+
+static const struct res_class subpool_res_class = {
+  .name = "subpool",
+  .dump = subpool_res_dump,
+  .detach = subpool_res_detach,
+  .free = subpool_res_free,
+};
+
+struct resource *
+res_subpool(struct respool *rp)
+{
+  ASSERT(!rp->subpool_of);
+  struct resource *r = res_new(&subpool_res_class, rp);
+  ASSERT(r);
+  ASSERT(r->rpool != rp);              // Avoid simple loops
+  rp->subpool_of = r;
+  return r;
+}
+
+#ifdef TEST
+
+int main(void)
+{
+  struct respool *rp = rp_new("interior", NULL);
+  struct respool *rp2 = rp_new("exterior", NULL);
+  rp_switch(rp);
+  res_malloc(10, NULL);
+  rp_switch(rp2);
+  res_malloc(7, NULL);
+  res_subpool(rp);
+  rp_dump(rp2, 0);
+  // rp_delete(rp);
+  // rp_dump(rp2, 0);
+  rp_delete(rp2);
+  return 0;
+}
+
+#endif
index 6a1687f3d51a96106ca6efe4feed0c1cf5427252..31cfc58a8272cb4bb88eb6fc6d7793a30d6e88ad 100644 (file)
@@ -33,6 +33,8 @@ rp_new(const char *name, struct mempool *mp)
 static void
 rp_free(struct respool *rp)
 {
+  if (rp->subpool_of)
+    res_detach(rp->subpool_of);
   if (!rp->mpool)
     xfree(rp);
   if (rp_current() == rp)
@@ -64,11 +66,17 @@ rp_detach(struct respool *rp)
 }
 
 void
-rp_dump(struct respool *rp)
+rp_dump(struct respool *rp, uns indent)
 {
-  printf("Resource pool %s at %p (%s):\n", (rp->name ? : "(noname)"), rp, (rp->mpool ? "mempool-based" : "freestanding"));
+  printf("%*sResource pool %s at %p (%s)%s:\n",
+        indent, "",
+        (rp->name ? : "(noname)"),
+        rp,
+        (rp->mpool ? "mempool-based" : "freestanding"),
+        (rp->subpool_of ? " (subpool)" : "")
+        );
   CLIST_FOR_EACH(struct resource *, r, rp->resources)
-    res_dump(r);
+    res_dump(r, indent+4);
 }
 
 struct resource *
@@ -110,12 +118,13 @@ res_free(struct resource *r)
 }
 
 void
-res_dump(struct resource *r)
+res_dump(struct resource *r, uns indent)
 {
-  printf("\t%p %s", r, r->rclass->name);
+  printf("%*s%p %s", indent, "", r, r->rclass->name);
   if (r->rclass->dump)
-    r->rclass->dump(r);
-  putchar('\n');
+    r->rclass->dump(r, indent+4);
+  else
+    putchar('\n');
 }
 
 #ifdef TEST
@@ -128,7 +137,7 @@ int main(void)
   struct respool *rp = rp_new("test", NULL);
   rp_switch(rp);
   struct fastbuf *f = bfdopen_shared(1, 0);
-  rp_dump(rp);
+  rp_dump(rp, 0);
   bputsn(f, "Hello, all worlds!");
   bclose(f);
   rp_delete(rp);
index 9764f12948bb0c5a7dada6ddbe855f7e0e1efcbc..24cc1df2d7e160f486176b109f024c48197ccdef 100644 (file)
@@ -10,7 +10,6 @@
 /*
  * FIXME:
  *     - check other candidates for resourcification
- *     - respool as a resource in another respool?
  *     - unit tests
  *     - automatic freeing of trans pool on thread exit
  */
@@ -25,6 +24,7 @@ struct respool {
   clist resources;
   const char *name;
   struct mempool *mpool;                               // If set, resources are allocated from the mempool, otherwise by xmalloc()
+  struct resource *subpool_of;
 };
 
 struct resource {
@@ -39,14 +39,14 @@ struct res_class {
   const char *name;
   void (*detach)(struct resource *r);
   void (*free)(struct resource *r);
-  void (*dump)(struct resource *r);
+  void (*dump)(struct resource *r, uns indent);
   uns res_size;                                                // Size of the resource structure (0=default)
 };
 
 struct respool *rp_new(const char *name, struct mempool *mp);
 void rp_delete(struct respool *rp);
 void rp_detach(struct respool *rp);
-void rp_dump(struct respool *rp);
+void rp_dump(struct respool *rp, uns indent);
 
 static inline struct respool *
 rp_current(void)
@@ -67,7 +67,7 @@ struct resource *res_alloc(const struct res_class *rc) LIKE_MALLOC;   // Returns N
 void res_drop(struct resource *r);
 void res_detach(struct resource *r);
 void res_free(struct resource *r);
-void res_dump(struct resource *r);
+void res_dump(struct resource *r, uns indent);
 
 static inline struct resource *                                // Returns NULL if there is no pool active
 res_new(const struct res_class *rc, void *priv)
@@ -89,4 +89,6 @@ void *res_malloc(size_t size, struct resource **ptr) LIKE_MALLOC;     // Allocates m
 void *res_malloc_zero(size_t size, struct resource **ptr) LIKE_MALLOC; // Allocates zero-initialized memory and creates a resource for it
 void *res_realloc(struct resource *res, size_t size);
 
+struct resource *res_subpool(struct respool *rp);      // Make @rp a sub-pool of the current pool
+
 #endif
index fffcf7503d03c7431aeb5286c08d297cb39fbc78..d91437b46cec344b25cc637a30d1cc8237b7e43b 100644 (file)
@@ -159,7 +159,7 @@ trans_dump(void)
       while (tx != t)
        {
          printf("Recovering transaction %p:\n", tx);
-         rp_dump(tx->rpool);
+         rp_dump(tx->rpool, 0);
          tx = tx->prev_trans;
        }
     }
@@ -172,7 +172,7 @@ trans_dump(void)
   while (t)
     {
       printf("Transaction %p:\n", t);
-      rp_dump(t->rpool);
+      rp_dump(t->rpool, 0);
       t = t->prev_trans;
     }
 }