From 847bb5125836ac3c89a9118be60cb077090f4756 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 2 Sep 2008 01:22:55 +0200 Subject: [PATCH] More work on resource pools. 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 | 4 +- ucw/respool.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ ucw/respool.h | 72 ++++++++++++++++++++++++++++++++++ ucw/trans.c | 14 +++++++ ucw/trans.h | 42 +------------------- 5 files changed, 195 insertions(+), 42 deletions(-) create mode 100644 ucw/respool.c create mode 100644 ucw/respool.h create mode 100644 ucw/trans.c diff --git a/ucw/Makefile b/ucw/Makefile index f7835977..4ff774e4 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -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 index 00000000..9a747cd4 --- /dev/null +++ b/ucw/respool.c @@ -0,0 +1,105 @@ +/* + * The UCW Library -- Resource Pools + * + * (c) 2008 Martin Mares + * + * 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 + +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 index 00000000..e06762e3 --- /dev/null +++ b/ucw/respool.h @@ -0,0 +1,72 @@ +/* + * The UCW Library -- Resource Pools + * + * (c) 2008 Martin Mares + * + * 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 index 00000000..1ceb3948 --- /dev/null +++ b/ucw/trans.c @@ -0,0 +1,14 @@ +/* + * The UCW Library -- Transactions + * + * (c) 2008 Martin Mares + * + * 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" + diff --git a/ucw/trans.h b/ucw/trans.h index 7ba8e6ff..66502037 100644 --- a/ucw/trans.h +++ b/ucw/trans.h @@ -10,54 +10,16 @@ #ifndef _UCW_TRANS_H #define _UCW_TRANS_H -#include "ucw/clists.h" #include "ucw/mempool.h" -#include - -/* 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 /* Transactions */ struct trans { struct trans *prev; struct mempool_state trans_pool_state; - struct respool res_pool; + struct respool *res_pool; jmp_buf jmp; }; -- 2.39.2