diff options
| author | krangelov <kr.angelov@gmail.com> | 2018-12-16 07:46:14 +0100 |
|---|---|---|
| committer | krangelov <kr.angelov@gmail.com> | 2018-12-16 07:46:14 +0100 |
| commit | eb2211217858d97256c802739531547c52d328a5 (patch) | |
| tree | 578060a42d79a4a7c12a60d964b7df7cbb051b02 /src/runtime/c/gu/mem.c | |
| parent | 083aa96e575554518dee32d03f579ad6cac26722 (diff) | |
a pool where the smallest chunks are memory pages
Diffstat (limited to 'src/runtime/c/gu/mem.c')
| -rw-r--r-- | src/runtime/c/gu/mem.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/src/runtime/c/gu/mem.c b/src/runtime/c/gu/mem.c index 3e5bd57a2..80e99242e 100644 --- a/src/runtime/c/gu/mem.c +++ b/src/runtime/c/gu/mem.c @@ -8,6 +8,10 @@ #include <sys/mman.h> #include <sys/stat.h> #endif +#if defined(__MINGW32__) || defined(_MSC_VER) +#include <malloc.h> +#endif + #if !defined(_MSC_VER) #include <unistd.h> #endif @@ -108,6 +112,39 @@ gu_mem_buf_alloc(size_t min_size, size_t* real_size_out) return gu_mem_buf_realloc(NULL, min_size, real_size_out); } +#if defined(__MINGW32__) || defined(_MSC_VER) +#include <windows.h> + +static int +getpagesize() +{ + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return system_info.dwPageSize; +} +#endif + +GU_API void* +gu_mem_page_alloc(size_t min_size, size_t* real_size_out) +{ + size_t page_size = getpagesize(); + size_t size = ((min_size + page_size - 1) / page_size) * page_size; + void *page = NULL; + +#if defined(ANDROID) + if ((page = memalign(page_size, size)) == NULL) { +#elif defined(__MINGW32__) || defined(_MSC_VER) + if ((page = malloc(size)) == NULL) { +#else + if (posix_memalign(&page, page_size, size) != 0) { +#endif + gu_fatal("Memory allocation failed"); + } + + *real_size_out = size; + return page; +} + GU_API void gu_mem_buf_free(void* buf) { @@ -132,6 +169,7 @@ struct GuFinalizerNode { enum GuPoolType { GU_POOL_HEAP, GU_POOL_LOCAL, + GU_POOL_PAGE, GU_POOL_MMAP }; @@ -180,6 +218,16 @@ gu_new_pool(void) return pool; } +GU_API GuPool* +gu_new_page_pool(void) +{ + size_t sz = GU_FLEX_SIZE(GuPool, init_buf, gu_mem_pool_initial_size); + uint8_t* buf = gu_mem_page_alloc(sz, &sz); + GuPool* pool = gu_init_pool(buf, sz); + pool->type = GU_POOL_PAGE; + return pool; +} + GU_API GuPool* gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr) { @@ -238,7 +286,10 @@ gu_pool_expand(GuPool* pool, size_t req) gu_mem_chunk_max_size)); gu_assert(real_req >= sizeof(GuMemChunk)); size_t size = 0; - GuMemChunk* chunk = gu_mem_buf_alloc(real_req, &size); + GuMemChunk* chunk = + (pool->type == GU_POOL_PAGE) + ? gu_mem_page_alloc(real_req, &size) + : gu_mem_buf_alloc(real_req, &size); chunk->next = pool->chunks; pool->chunks = chunk; pool->curr_buf = (uint8_t*) chunk; @@ -309,6 +360,7 @@ gu_malloc_prefixed(GuPool* pool, size_t pre_align, size_t pre_size, size_t full_size = gu_mem_advance(offsetof(GuMemChunk, data), pre_align, pre_size, align, size); if (full_size > gu_mem_max_shared_alloc && + pool->type != GU_POOL_PAGE && pool->type != GU_POOL_MMAP) { GuMemChunk* chunk = gu_mem_alloc(full_size); chunk->next = pool->chunks; |
