summaryrefslogtreecommitdiff
path: root/net/bird3/files/patch-10-stonehenge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bird3/files/patch-10-stonehenge')
-rw-r--r--net/bird3/files/patch-10-stonehenge116
1 files changed, 116 insertions, 0 deletions
diff --git a/net/bird3/files/patch-10-stonehenge b/net/bird3/files/patch-10-stonehenge
new file mode 100644
index 000000000000..a640442dae8d
--- /dev/null
+++ b/net/bird3/files/patch-10-stonehenge
@@ -0,0 +1,116 @@
+From f6ef8b5b58c674dd270b40aa57d20d2d638c48e9 Mon Sep 17 00:00:00 2001
+From: Maria Matejka <mq@ucw.cz>
+Date: Tue, 24 Dec 2024 12:18:39 +0100
+Subject: [PATCH] Stonehenge: multi-slab allocator
+
+To mid-term allocate and free lots of small blocks in a fast pace,
+mb_alloc is too slow and causes heap bloating. We can already allocate
+blocks from slabs, and if we allow for a little bit of inefficiency,
+we can just use multiple slabs with stepped sizes.
+
+This technique is already used in ea_list allocation which is gonna be
+converted to Stonehenge.
+---
+ lib/resource.h | 14 ++++++++++++
+ lib/slab.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 76 insertions(+)
+
+diff --git a/lib/resource.h b/lib/resource.h
+index 48bf1f9ba..12b788510 100644
+--- lib/resource.h
++++ lib/resource.h
+@@ -139,6 +139,20 @@ void *sl_allocz(slab *);
+ void sl_free(void *);
+ void sl_delete(slab *);
+
++/* A whole stonehenge of slabs */
++
++typedef struct stonehenge stonehenge;
++typedef struct sth_block {
++ void *block;
++ bool large;
++} sth_block;
++
++stonehenge *sth_new(pool *);
++sth_block sth_alloc(stonehenge *, uint size);
++sth_block sth_allocz(stonehenge *, uint size);
++void sth_free(sth_block);
++void sth_delete(stonehenge *);
++
+ /*
+ * Low-level memory allocation functions, please don't use
+ * outside resource manager and possibly sysdep code.
+diff --git a/lib/slab.c b/lib/slab.c
+index ca971f9fb..d68bfef1e 100644
+--- lib/slab.c
++++ lib/slab.c
+@@ -469,4 +469,66 @@ slab_lookup(resource *r, unsigned long a)
+ return NULL;
+ }
+
++static const uint stonehenge_sizes[] = { 56, 112, 168, 288, 448, 800, 1344 };
++
++struct stonehenge {
++ pool *p;
++ slab *s[ARRAY_SIZE(stonehenge_sizes)];
++};
++
++sth_block
++sth_alloc(stonehenge *sth, uint size)
++{
++ for (uint i=0; i<ARRAY_SIZE(stonehenge_sizes); i++)
++ if (size <= stonehenge_sizes[i])
++ {
++ if (!sth->s[i])
++ sth->s[i] = sl_new(sth->p, stonehenge_sizes[i]);
++
++ return (sth_block) { .block = sl_alloc(sth->s[i]), };
++ }
++
++ return (sth_block) {
++ .block = mb_alloc(sth->p, size),
++ .large = 1,
++ };
++}
++
++sth_block
++sth_allocz(stonehenge *sth, uint size)
++{
++ sth_block b = sth_alloc(sth, size);
++ bzero(b.block, size);
++ return b;
++}
++
++void
++sth_free(sth_block b)
++{
++ if (b.large)
++ mb_free(b.block);
++ else
++ sl_free(b.block);
++}
++
++stonehenge *
++sth_new(pool *pp)
++{
++ stonehenge tmps = {
++ .p = rp_new(pp, pp->domain, "Stonehenge"),
++ };
++
++ stonehenge *s = sth_alloc(&tmps, sizeof(stonehenge)).block;
++ *s = tmps;
++ return s;
++}
++
++void sth_delete(stonehenge *s)
++{
++ pool *p = s->p;
++ sth_free((sth_block) { s });
++ rp_free(p);
++}
++
++
+ #endif
+--
+GitLab
+