ports/net/bird3/files/patch-10-stonehenge
Olivier Cochard 4516e09a23 net/bird3: Add new branch 3.x (multithreaded)
Warning: Consider version 3.0.0 to be unstable.

PR:		283403
Sponsored by:	Netflix
2025-01-09 23:07:38 +01:00

116 lines
2.6 KiB
Text

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