summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/bitmap_test.c3
-rw-r--r--lib/buffer_test.c1
-rw-r--r--lib/event.c2
-rw-r--r--lib/event_test.c1
-rw-r--r--lib/flowspec_test.c11
-rw-r--r--lib/hash.h6
-rw-r--r--lib/hash_test.c1
-rw-r--r--lib/lists.h1
-rw-r--r--lib/mempool.c48
-rw-r--r--lib/resource.c3
-rw-r--r--lib/resource.h16
-rw-r--r--lib/slab.c17
-rw-r--r--lib/timer.c1
13 files changed, 75 insertions, 36 deletions
diff --git a/lib/bitmap_test.c b/lib/bitmap_test.c
index 0595a4d0..07860c94 100644
--- a/lib/bitmap_test.c
+++ b/lib/bitmap_test.c
@@ -24,7 +24,6 @@ t_bmap_set_clear_random(void)
{
struct bmap b;
- resource_init();
bmap_init(&b, &root_pool, 1024);
char expected[MAX_NUM] = {};
@@ -60,7 +59,6 @@ t_hmap_set_clear_random(void)
{
struct hmap b;
- resource_init();
hmap_init(&b, &root_pool, 1024);
char expected[MAX_NUM] = {};
@@ -119,7 +117,6 @@ t_hmap_set_clear_fill(void)
{
struct hmap b;
- resource_init();
hmap_init(&b, &root_pool, 1024);
char expected[MAX_NUM] = {};
diff --git a/lib/buffer_test.c b/lib/buffer_test.c
index 5b7de330..0629e901 100644
--- a/lib/buffer_test.c
+++ b/lib/buffer_test.c
@@ -41,7 +41,6 @@ fill_expected_array(void)
static void
init_buffer(void)
{
- resource_init();
buffer_pool = &root_pool;
BUFFER_INIT(buf, buffer_pool, MAX_NUM);
}
diff --git a/lib/event.c b/lib/event.c
index 273447e0..33dc00b0 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -157,6 +157,7 @@ ev_run_list(event_list *l)
io_log_event(e->hook, e->data);
ev_run(e);
+ tmp_flush();
}
return !EMPTY_LIST(*l);
@@ -184,6 +185,7 @@ ev_run_list_limited(event_list *l, uint limit)
io_log_event(e->hook, e->data);
ev_run(e);
+ tmp_flush();
limit--;
}
diff --git a/lib/event_test.c b/lib/event_test.c
index e1215bba..e1fbea8f 100644
--- a/lib/event_test.c
+++ b/lib/event_test.c
@@ -53,7 +53,6 @@ t_ev_run_list(void)
{
int i;
- resource_init();
olock_init();
timer_init();
io_init();
diff --git a/lib/flowspec_test.c b/lib/flowspec_test.c
index ed4afe51..03649b99 100644
--- a/lib/flowspec_test.c
+++ b/lib/flowspec_test.c
@@ -446,10 +446,7 @@ t_validation6(void)
static int
t_builder4(void)
{
- resource_init();
-
struct flow_builder *fb = flow_builder_init(&root_pool);
- linpool *lp = lp_new_default(&root_pool);
/* Expectation */
@@ -492,7 +489,7 @@ t_builder4(void)
flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
flow_builder_add_op_val(fb, 0, 0x55);
- net_addr_flow4 *res = flow_builder4_finalize(fb, lp);
+ net_addr_flow4 *res = flow_builder4_finalize(fb, tmp_linpool);
bt_assert(memcmp(res, expect, expect->length) == 0);
@@ -529,8 +526,6 @@ t_builder6(void)
{
net_addr_ip6 ip;
- resource_init();
- linpool *lp = lp_new_default(&root_pool);
struct flow_builder *fb = flow_builder_init(&root_pool);
fb->ipv6 = 1;
@@ -574,7 +569,7 @@ t_builder6(void)
flow_builder_set_type(fb, FLOW_TYPE_LABEL);
flow_builder_add_op_val(fb, 0, 0x55);
- net_addr_flow6 *res = flow_builder6_finalize(fb, lp);
+ net_addr_flow6 *res = flow_builder6_finalize(fb, tmp_linpool);
bt_assert(memcmp(res, expect, expect->length) == 0);
/* Reverse order */
@@ -601,7 +596,7 @@ t_builder6(void)
flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
flow_builder6_add_pfx(fb, &ip, 61);
- res = flow_builder6_finalize(fb, lp);
+ res = flow_builder6_finalize(fb, tmp_linpool);
bt_assert(memcmp(res, expect, expect->length) == 0);
return 1;
diff --git a/lib/hash.h b/lib/hash.h
index ea4ca6dd..8febb33f 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -215,6 +215,12 @@ mem_hash_mix(u64 *h, const void *p, uint s)
*h = *h * multiplier + pp[i];
}
+static inline void
+mem_hash_mix_num(u64 *h, u64 val)
+{
+ mem_hash_mix(h, &val, sizeof(val));
+}
+
static inline uint
mem_hash_value(u64 *h)
{
diff --git a/lib/hash_test.c b/lib/hash_test.c
index 59beb7c0..4bce7017 100644
--- a/lib/hash_test.c
+++ b/lib/hash_test.c
@@ -61,7 +61,6 @@ dump_nodes(void)
static void
init_hash_(uint order)
{
- resource_init();
my_pool = rp_new(&root_pool, "Test pool");
HASH_INIT(hash, my_pool, order);
diff --git a/lib/lists.h b/lib/lists.h
index 479f4ed1..7e6d5467 100644
--- a/lib/lists.h
+++ b/lib/lists.h
@@ -42,6 +42,7 @@ typedef union list { /* In fact two overlayed nodes */
};
} list;
+#define STATIC_LIST_INIT(name) name = { .head = &name.tail_node, .tail = &name.head_node, .null = NULL }
#define NODE (node *)
#define HEAD(list) ((void *)((list).head))
diff --git a/lib/mempool.c b/lib/mempool.c
index 90d7c774..c75f1f5b 100644
--- a/lib/mempool.c
+++ b/lib/mempool.c
@@ -39,9 +39,11 @@ struct linpool {
byte *ptr, *end;
struct lp_chunk *first, *current; /* Normal (reusable) chunks */
struct lp_chunk *first_large; /* Large chunks */
- uint chunk_size, threshold, total, total_large;
+ uint chunk_size, threshold, total:31, use_pages:1, total_large;
};
+_Thread_local linpool *tmp_linpool;
+
static void lp_free(resource *);
static void lp_dump(resource *);
static resource *lp_lookup(resource *, unsigned long);
@@ -69,6 +71,12 @@ linpool
*lp_new(pool *p, uint blk)
{
linpool *m = ralloc(p, &lp_class);
+ if (!blk)
+ {
+ m->use_pages = 1;
+ blk = page_size - lp_chunk_size;
+ }
+
m->chunk_size = blk;
m->threshold = 3*blk/4;
return m;
@@ -121,7 +129,11 @@ lp_alloc(linpool *m, uint size)
else
{
/* Need to allocate a new chunk */
- c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
+ if (m->use_pages)
+ c = alloc_page();
+ else
+ c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
+
m->total += m->chunk_size;
c->next = NULL;
c->size = m->chunk_size;
@@ -258,7 +270,10 @@ lp_free(resource *r)
for(d=m->first; d; d = c)
{
c = d->next;
- xfree(d);
+ if (m->use_pages)
+ free_page(d);
+ else
+ xfree(d);
}
for(d=m->first_large; d; d = c)
{
@@ -291,19 +306,24 @@ static struct resmem
lp_memsize(resource *r)
{
linpool *m = (linpool *) r;
- struct lp_chunk *c;
- int cnt = 0;
+ struct resmem sz = {
+ .overhead = sizeof(struct linpool) + ALLOC_OVERHEAD,
+ };
- for(c=m->first; c; c=c->next)
- cnt++;
- for(c=m->first_large; c; c=c->next)
- cnt++;
+ for (struct lp_chunk *c = m->first_large; c; c = c->next)
+ {
+ sz.effective += c->size;
+ sz.overhead += lp_chunk_size + ALLOC_OVERHEAD;
+ }
- return (struct resmem) {
- .effective = m->total + m->total_large,
- .overhead = ALLOC_OVERHEAD + sizeof(struct linpool) +
- cnt * (ALLOC_OVERHEAD + sizeof(struct lp_chunk)),
- };
+ uint regular = 0;
+ for (struct lp_chunk *c = m->first; c; c = c->next)
+ regular++;
+
+ sz.effective += m->chunk_size * regular;
+ sz.overhead += (lp_chunk_size + ALLOC_OVERHEAD) * regular;
+
+ return sz;
}
diff --git a/lib/resource.c b/lib/resource.c
index 5d4c7780..a179afe3 100644
--- a/lib/resource.c
+++ b/lib/resource.c
@@ -270,9 +270,12 @@ rlookup(unsigned long a)
void
resource_init(void)
{
+ resource_sys_init();
+
root_pool.r.class = &pool_class;
root_pool.name = "Root";
init_list(&root_pool.inside);
+ tmp_init(&root_pool);
}
/**
diff --git a/lib/resource.h b/lib/resource.h
index 9ec41ed8..313b01dc 100644
--- a/lib/resource.h
+++ b/lib/resource.h
@@ -79,10 +79,19 @@ void lp_flush(linpool *); /* Free everything, but leave linpool */
void lp_save(linpool *m, lp_state *p); /* Save state */
void lp_restore(linpool *m, lp_state *p); /* Restore state */
+extern _Thread_local linpool *tmp_linpool; /* Temporary linpool autoflushed regularily */
+
+#define tmp_alloc(sz) lp_alloc(tmp_linpool, sz)
+#define tmp_allocu(sz) lp_allocu(tmp_linpool, sz)
+#define tmp_allocz(sz) lp_allocz(tmp_linpool, sz)
+
+#define tmp_init(p) tmp_linpool = lp_new_default(p)
+#define tmp_flush() lp_flush(tmp_linpool)
+
extern const int lp_chunk_size;
#define LP_GAS 1024
#define LP_GOOD_SIZE(x) (((x + LP_GAS - 1) & (~(LP_GAS - 1))) - lp_chunk_size)
-#define lp_new_default(p) lp_new(p, LP_GOOD_SIZE(LP_GAS*4))
+#define lp_new_default(p) lp_new(p, 0)
/* Slabs */
@@ -101,10 +110,11 @@ void sl_free(slab *, void *);
void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_size);
/* Allocator of whole pages; for use in slabs and other high-level allocators. */
-u64 get_page_size(void);
+extern long page_size;
void *alloc_page(void);
void free_page(void *);
-extern uint pages_kept;
+
+void resource_sys_init(void);
#ifdef HAVE_LIBDMALLOC
/*
diff --git a/lib/slab.c b/lib/slab.c
index 1d844bab..9be9844d 100644
--- a/lib/slab.c
+++ b/lib/slab.c
@@ -180,7 +180,7 @@ struct sl_alignment { /* Magic structure for testing of alignment */
int x[0];
};
-#define SL_GET_HEAD(x) ((struct sl_head *) (((uintptr_t) (x)) & ~(get_page_size()-1)))
+#define SL_GET_HEAD(x) ((struct sl_head *) (((uintptr_t) (x)) & ~(page_size-1)))
/**
* sl_new - create a new Slab
@@ -202,7 +202,6 @@ sl_new(pool *p, uint size)
s->obj_size = size;
s->head_size = sizeof(struct sl_head);
- u64 page_size = get_page_size();
do {
s->objs_per_slab = (page_size - s->head_size) / size;
@@ -272,6 +271,9 @@ no_partial:
goto okay;
}
h = alloc_page();
+#ifdef POISON
+ memset(h, 0xba, page_size);
+#endif
ASSERT_DIE(SL_GET_HEAD(h) == h);
memset(h, 0, s->head_size);
add_head(&s->partial_heads, &h->n);
@@ -327,7 +329,12 @@ sl_free(slab *s, void *oo)
{
rem_node(&h->n);
if (s->num_empty_heads >= MAX_EMPTY_HEADS)
+ {
+#ifdef POISON
+ memset(h, 0xde, page_size);
+#endif
free_page(h);
+ }
else
{
add_head(&s->empty_heads, &h->n);
@@ -391,7 +398,7 @@ slab_memsize(resource *r)
return (struct resmem) {
.effective = eff,
- .overhead = ALLOC_OVERHEAD + sizeof(struct slab) + heads * get_page_size() - eff,
+ .overhead = ALLOC_OVERHEAD + sizeof(struct slab) + heads * page_size - eff,
};
}
@@ -402,10 +409,10 @@ slab_lookup(resource *r, unsigned long a)
struct sl_head *h;
WALK_LIST(h, s->partial_heads)
- if ((unsigned long) h < a && (unsigned long) h + get_page_size() < a)
+ if ((unsigned long) h < a && (unsigned long) h + page_size < a)
return r;
WALK_LIST(h, s->full_heads)
- if ((unsigned long) h < a && (unsigned long) h + get_page_size() < a)
+ if ((unsigned long) h < a && (unsigned long) h + page_size < a)
return r;
return NULL;
}
diff --git a/lib/timer.c b/lib/timer.c
index 381163d0..c47e0bbc 100644
--- a/lib/timer.c
+++ b/lib/timer.c
@@ -233,6 +233,7 @@ timers_fire(struct timeloop *loop)
io_log_event(t->hook, t->data);
t->hook(t);
+ tmp_flush();
}
}