]> mj.ucw.cz Git - libucw.git/commitdiff
More work on resource pools.
authorMartin Mares <mj@ucw.cz>
Mon, 1 Sep 2008 23:22:55 +0000 (01:22 +0200)
committerMartin Mares <mj@ucw.cz>
Tue, 29 Mar 2011 10:55:05 +0000 (12:55 +0200)
I really do not like that the respools use two different types of memory
allocation, but I really want them to be as efficient as possible inside
transactions and we do not have a good thread-local allocator yet.

ucw/Makefile
ucw/respool.c [new file with mode: 0644]
ucw/respool.h [new file with mode: 0644]
ucw/trans.c [new file with mode: 0644]
ucw/trans.h

index f7835977e8a6fcc73848d67443e51ae991108c40..4ff774e462a2bd7acadd736694a80a29985e61b5 100644 (file)
@@ -34,7 +34,7 @@ LIBUCW_MODS= \
        bbuf gary \
        getopt \
        strtonum \
-       trans
+       respool trans
 
 LIBUCW_MAIN_INCLUDES= \
        lib.h log.h threads.h \
@@ -61,7 +61,7 @@ LIBUCW_MAIN_INCLUDES= \
        kmp.h kmp-search.h binsearch.h \
        partmap.h \
        strtonum.h \
-       trans.h
+       respool.h trans.h
 
 ifdef CONFIG_UCW_THREADS
 # Some modules require threading
diff --git a/ucw/respool.c b/ucw/respool.c
new file mode 100644 (file)
index 0000000..9a747cd
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *     The UCW Library -- Resource Pools
+ *
+ *     (c) 2008 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 "ucw/mempool.h"
+
+#include <stdio.h>
+
+struct respool *
+rp_new(const char *name, struct mempool *mp)
+{
+  struct respool *rp;
+
+  if (mp)
+    {
+      rp = mp_alloc_zero(mp, sizeof(*rp));
+      rp->mpool = mp;
+    }
+  else
+    rp = xmalloc_zero(sizeof(*rp));
+  clist_init(&rp->resources);
+  rp->name = name;
+  return rp;
+}
+
+void
+rp_delete(struct respool *rp)
+{
+  struct resource *r;
+  while (r = clist_tail(&rp->resources))
+    res_free(r);
+  if (!rp->mpool)
+    xfree(rp);
+}
+
+void
+rp_dump(struct respool *rp)
+{
+  printf("Resource pool %s at %p (%s):\n", (rp->name ? : "(noname)"), rp, (rp->mpool ? "mempool-based" : "freestanding"));
+  CLIST_FOR_EACH(struct resource *, r, rp->resources)
+    res_dump(r);
+}
+
+struct resource *
+res_alloc(void)
+{
+  struct respool *rp = rp_current();
+  if (!rp)
+    return NULL;
+
+  struct resource *r = (rp->mpool ? mp_alloc_fast(rp->mpool, sizeof(*r)) : xmalloc(sizeof(*r)));
+  clist_add_tail(&rp->resources, &r->n);
+  return r;
+}
+
+static inline void
+res_do_free(struct resource *r)
+{
+  clist_remove(&r->n);
+  if (!r->rpool->mpool)
+    xfree(r);
+}
+
+void
+res_detach(struct resource *r)
+{
+  if (r->rclass->detach)
+    r->rclass->detach(r);
+  res_do_free(r);
+}
+
+void
+res_free(struct resource *r)
+{
+  if (r->rclass->free)
+    r->rclass->free(r);
+  res_do_free(r);
+}
+
+void
+res_dump(struct resource *r)
+{
+  printf("\t%p %s", r, r->rclass->name);
+  if (r->rclass->dump)
+    r->rclass->dump(r);
+  putchar('\n');
+}
+
+#ifdef TEST
+
+int main(void)
+{
+  struct respool *rp = rp_new("test", NULL);
+  rp_dump(rp);
+  return 0;
+}
+
+#endif
diff --git a/ucw/respool.h b/ucw/respool.h
new file mode 100644 (file)
index 0000000..e06762e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *     The UCW Library -- Resource Pools
+ *
+ *     (c) 2008 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#ifndef _UCW_RESPOOL_H
+#define _UCW_RESPOOL_H
+
+#include "ucw/clists.h"
+#include "ucw/threads.h"
+
+struct respool {
+  clist resources;
+  const char *name;
+  struct mempool *mpool;                               // If set, resources are allocated from the mempool, otherwise by xmalloc()
+};
+
+struct resource {
+  cnode n;
+  struct respool *rpool;
+  struct res_class *rclass;
+  void *priv;                                          // Private to the class
+};
+
+struct res_class {
+  const char *name;
+  void (*detach)(struct resource *r);
+  void (*free)(struct resource *r);
+  void (*dump)(struct resource *r);
+};
+
+struct respool *rp_new(const char *name, struct mempool *mp);
+void rp_delete(struct respool *rp);
+void rp_dump(struct respool *rp);
+
+static inline struct respool *
+rp_current(void)
+{
+  return ucwlib_thread_context()->current_respool;     // May be NULL
+}
+
+static inline struct respool *
+rp_switch(struct respool *rp)
+{
+  struct ucwlib_context *ctx = ucwlib_thread_context();
+  struct respool *orp = ctx->current_respool;
+  ctx->current_respool = rp;
+  return orp;
+}
+
+struct resource *res_alloc(void);                      // Returns NULL if there is no pool active
+void res_detach(struct resource *r);
+void res_free(struct resource *r);
+void res_dump(struct resource *r);
+
+static inline struct resource *                                // Returns NULL if there is no pool active
+res_new(struct res_class *rc, void *priv)
+{
+  struct resource *r = res_alloc();
+  if (r)
+    {
+      r->rclass = rc;
+      r->priv = priv;
+    }
+  return r;
+}
+
+#endif
diff --git a/ucw/trans.c b/ucw/trans.c
new file mode 100644 (file)
index 0000000..1ceb394
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ *     The UCW Library -- Transactions
+ *
+ *     (c) 2008 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/trans.h"
+#include "ucw/respool.h"
+#include "ucw/mempool.h"
+
index 7ba8e6ff53827df4cf4439402aac964d840e798b..665020370ddb27f6f3eacaa3d9c350d6fffaa27b 100644 (file)
 #ifndef _UCW_TRANS_H
 #define _UCW_TRANS_H
 
-#include "ucw/clists.h"
 #include "ucw/mempool.h"
 
-#include <jmpbuf.h>
-
-/* Resource pools */
-
-struct respool {
-  clist resources;
-  struct mempool *mp;          // If set, resources are allocated from the mempool, otherwise by xmalloc()
-};
-
-struct resource {
-  cnode n;
-  struct res_class *rclass;
-  void *priv;                  // Private to the class
-};
-
-struct res_class {
-  const char *name;
-  void (*undo)(struct res *t);
-  void (*dump)(struct res *t);
-};
-
-struct respool *rp_new(void);
-void rp_delete(struct respool *rp);
-void rp_dump(struct respool *rp);
-
-struct resource *res_alloc(struct respool *rp);
-void res_fix(struct resource *r);
-void res_undo(struct resource *r);
-void res_dump(struct resource *r);
-
-static inline struct resource *
-res_new(struct respool *rp, struct res_class *rc, void *priv)
-{
-  struct resource *r = res_alloc(rp);
-  r->rclass = rc;
-  r->priv = priv;
-  return r;
-}
+#include <setjmp.h>
 
 /* Transactions */
 
 struct trans {
   struct trans *prev;
   struct mempool_state trans_pool_state;
-  struct respool res_pool;
+  struct respool *res_pool;
   jmp_buf jmp;
 };