Workshop o mikrokontrolérech na SKSP 2024.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
3.2 KiB

2 months ago
/*
* The UCW Library -- Resource Pools
*
* (c) 2008--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/resource.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;
rp->default_res_flags = RES_FLAG_TEMP;
return rp;
}
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)
rp_switch(NULL);
}
void
rp_delete(struct respool *rp)
{
struct resource *r;
while (r = clist_tail(&rp->resources))
{
ASSERT(r->rpool == rp);
res_free(r);
}
rp_free(rp);
}
void
rp_detach(struct respool *rp)
{
struct resource *r;
while (r = clist_head(&rp->resources))
{
ASSERT(r->rpool == rp);
res_detach(r);
}
rp_free(rp);
}
void
rp_commit(struct respool *rp)
{
struct resource *r;
while (r = clist_head(&rp->resources))
{
ASSERT(r->rpool == rp);
if (r->flags & RES_FLAG_TEMP)
res_free(r);
else
res_detach(r);
}
rp_free(rp);
}
void
rp_dump(struct respool *rp, uint indent)
{
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, indent+4);
}
struct resource *
res_alloc(const struct res_class *rc)
{
struct respool *rp = rp_current();
ASSERT(rp);
uint size = (rc->res_size ? : sizeof(struct resource));
struct resource *r;
if (rp->mpool)
{
r = mp_alloc_fast(rp->mpool, size);
r->flags = 0;
}
else
{
r = xmalloc(size);
r->flags = RES_FLAG_XFREE;
}
res_add(r);
return r;
}
void
res_add(struct resource *r)
{
struct respool *rp = rp_current();
ASSERT(rp);
r->rpool = rp;
clist_add_tail(&rp->resources, &r->n);
r->flags &= ~RES_FLAG_TEMP;
r->flags |= rp->default_res_flags & RES_FLAG_TEMP;
}
void
res_drop(struct resource *r)
{
clist_remove(&r->n);
if (r->flags & RES_FLAG_XFREE)
xfree(r);
}
void
res_detach(struct resource *r)
{
if (!r)
return;
if (r->rclass->detach)
r->rclass->detach(r);
res_drop(r);
}
void
res_free(struct resource *r)
{
if (!r)
return;
if (r->rclass->free)
r->rclass->free(r);
res_drop(r);
}
void
res_dump(struct resource *r, uint indent)
{
printf("%*s%p %s %s", indent, "", r, ((r->flags & RES_FLAG_TEMP) ? "TEMP" : "PERM"), r->rclass->name);
if (r->rclass->dump)
r->rclass->dump(r, indent+4);
else
putchar('\n');
}
#ifdef TEST
#include <ucw/fastbuf.h>
int main(void)
{
// struct mempool *mp = mp_new(4096);
struct respool *rp = rp_new("test", NULL);
rp_switch(rp);
struct fastbuf *f = bfdopen_shared(1, 0);
rp_dump(rp, 0);
bputsn(f, "Hello, all worlds!");
bclose(f);
rp_delete(rp);
return 0;
}
#endif