diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-06-03 17:09:15 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-06-03 17:09:15 +0100 |
commit | 6dbf2e4e35b7be68774ae4a87e582742cb1258f5 (patch) | |
tree | c08fdceac841a4013e6e13d1b45197b8c64af6e4 /contrib | |
parent | 98f9ed8e84873dad4c1e65454a2bddd2a0dae4b0 (diff) | |
download | rspamd-6dbf2e4e35b7be68774ae4a87e582742cb1258f5.tar.gz rspamd-6dbf2e4e35b7be68774ae4a87e582742cb1258f5.zip |
[Minor] Arm64: Implement poor man slabs
Issue: #2906
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/lua-lpeg/lpvm.c | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/contrib/lua-lpeg/lpvm.c b/contrib/lua-lpeg/lpvm.c index 711fe026d..441712826 100644 --- a/contrib/lua-lpeg/lpvm.c +++ b/contrib/lua-lpeg/lpvm.c @@ -19,6 +19,20 @@ #include <sys/mman.h> +#define MAX_PIECES (1u << 2u) + +/* 64 bytes, 1 cache line */ +struct poor_slab { + struct slab_piece { + unsigned char *ptr; + uint32_t sz; + uint32_t occupied; + } pieces[MAX_PIECES]; +}; + +/* Used to optimize pages allocation */ +struct poor_slab slabs; + static uint64_t xorshifto_seed[2] = {0xdeadbabe, 0xdeadbeef}; static inline uint64_t @@ -33,6 +47,15 @@ lpeg_allocate_mem_low (size_t sz) unsigned flags = MAP_PRIVATE | MAP_ANON; void *base_addr = NULL; + /* Check slabs */ + for (unsigned i = 0; i < MAX_PIECES; i ++) { + if (!slabs.pieces[i].occupied && slabs.pieces[i].sz == sz) { + /* Reuse, short path */ + slabs.pieces[i].occupied = 1; + return slabs.pieces[i].ptr + sizeof (size_t); + } + } + #ifdef MAP_32BIT flags |= MAP_32BIT; #else @@ -52,6 +75,25 @@ lpeg_allocate_mem_low (size_t sz) assert (cp != NULL); memcpy (cp, &sz, sizeof (sz)); + for (unsigned i = 0; i < MAX_PIECES; i ++) { + if (slabs.pieces[i].sz == 0) { + /* Store piece */ + slabs.pieces[i].sz = sz; + slabs.pieces[i].ptr = cp; + slabs.pieces[i].occupied = 1; + + return cp + sizeof (sz); + } + } + + /* Not enough free pieces, pop some */ + unsigned sel = ((uintptr_t)cp) & ((MAX_PIECES * 2) - 1); + /* Here we free memory in fact */ + munmap (slabs.pieces[sel].ptr, slabs.pieces[sel].sz); + slabs.pieces[sel].sz = sz; + slabs.pieces[sel].ptr = cp; + slabs.pieces[sel].occupied = 1; + return cp + sizeof (sz); } @@ -61,8 +103,20 @@ lpeg_free_mem_low(void *p) unsigned char *cp = (unsigned char *)p; size_t sz; - memcpy (&sz, cp - sizeof (sz), sizeof (sz)); - munmap (cp - sizeof (sz), sz + sizeof (sz)); + /* Base address */ + cp -= sizeof (sz); + memcpy (&sz, cp, sizeof (sz)); + + for (unsigned i = 0; i < MAX_PIECES; i ++) { + if (slabs.pieces[i].occupied && slabs.pieces[i].ptr == cp) { + /* Return back */ + slabs.pieces[i].occupied = 0; + + return; + } + } + + /* No match, unmapped by allocation */ } /* initial size for call/backtrack stack */ |