diff options
author | Maria Matejka <mq@ucw.cz> | 2021-09-08 11:29:49 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2021-10-13 19:01:22 +0200 |
commit | 6cd37713781a3092f8166b2178fae35cbfec1e28 (patch) | |
tree | d80aaadbbd0b39765f6284229420dea754618c45 /sysdep/unix/alloc.c | |
parent | 3a31c3aad6c53ea9673743f983e13728d8551149 (diff) |
Multipage allocation
We can also quite simply allocate bigger blocks. Anyway, we need these
blocks to be aligned to their size which needs one mmap() two times
bigger and then two munmap()s returning the unaligned parts.
The user can specify -B <N> on startup when <N> is the exponent of 2,
setting the block size to 2^N. On most systems, N is 12, anyway if you
know that your configuration is going to eat gigabytes of RAM, you are
almost forced to raise your block size as you may easily get into memory
fragmentation issues or you have to raise your maximum mapping count,
e.g. "sysctl vm.max_map_count=(number)".
Diffstat (limited to 'sysdep/unix/alloc.c')
-rw-r--r-- | sysdep/unix/alloc.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sysdep/unix/alloc.c b/sysdep/unix/alloc.c index f6296afe..4c9d5eb5 100644 --- a/sysdep/unix/alloc.c +++ b/sysdep/unix/alloc.c @@ -17,6 +17,7 @@ #endif long page_size = 0; +_Bool alloc_multipage = 0; #ifdef HAVE_MMAP static _Bool use_fake = 0; @@ -45,9 +46,31 @@ alloc_sys_page(void) #ifdef HAVE_MMAP if (!use_fake) { + if (alloc_multipage) + { + void *big = mmap(NULL, page_size * 2, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (big == MAP_FAILED) + bug("mmap(%lu) failed: %m", page_size); + + uintptr_t offset = ((uintptr_t) big) % page_size; + if (offset) + { + void *ret = big + page_size - offset; + munmap(big, page_size - offset); + munmap(ret + page_size, offset); + return ret; + } + else + { + munmap(big + page_size, page_size); + return big; + } + } + void *ret = mmap(NULL, page_size, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (ret == MAP_FAILED) bug("mmap(%lu) failed: %m", page_size); + return ret; } else |