32#include <emscripten.h>
38#include <sys/resource.h>
47#if defined(__x86_64__) || defined(_M_X64) || defined(__ppc64__) || defined(__LP64__)
50#define struct_align 16
58typedef struct __attribute__((aligned(struct_align))) sfpool_t {
63 uint32_t total_blocks;
78static_assert(
sizeof(ptr_t) ==
sizeof(
void*),
"Unknown memory pointer size detected");
80static inline bool _is_in_pool(sfpool_t *pool,
const void *ptr) {
81 volatile ptr_t p = (ptr_t)ptr;
82 return(p >= (ptr_t)pool->data
83 && p < (ptr_t)(pool->data + pool->total_bytes));
100 register uint32_t *p = (uint32_t*)ptr;
101 register uint32_t s = (size>>2);
102 while (s--) *p++ = 0x0;
114 register ptr_t mask = ptr_align - 1;
115 ptr_t aligned = ((ptr_t)ptr + mask) & ~mask;
116 return (
void*)aligned;
130#if defined(__EMSCRIPTEN__)
131 res = (uint8_t *)malloc(size+ptr_align);
133 res = VirtualAlloc(NULL, size+ptr_align,
134 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
135#elif defined(__APPLE__)
136 int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
137 res = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
140 int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
142 if (getrlimit(RLIMIT_MEMLOCK, &rl) == 0)
143 if(size<=rl.rlim_cur) flags |= MAP_LOCKED;
144 res = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
158#if defined(__EMSCRIPTEN__)
161 VirtualFree(ptr, 0, MEM_RELEASE);
163 munmap(ptr, size +ptr_align);
186size_t sfpool_init(sfpool_t *pool,
size_t nmemb,
size_t blocksize) {
187 if((blocksize & (blocksize - 1)) != 0)
return 0;
189 size_t totalsize = nmemb * blocksize;
191 if (pool->buffer == NULL)
return 0;
194 if (pool->data == NULL)
return 0;
196 pool->total_bytes = totalsize;
197 pool->total_blocks = nmemb;
198 pool->block_size = blocksize;
200 pool->free_list = pool->data;
201 register uint32_t i, bi;
202 for (i = 0; i < pool->total_blocks - 1; ++i) {
204 *(uint8_t **)(pool->data + bi) =
205 pool->data + bi + blocksize;
207 pool->free_count = pool->total_blocks;
209 (pool->data + (pool->total_blocks - 1) * blocksize) = NULL;
211 pool->miss_total = pool->miss_bytes = 0;
212 pool->hits_total = pool->hits_bytes = 0;
213 pool->alloc_total = 0;
230 pool->miss_total = pool->miss_bytes = 0;
231 pool->hits_total = pool->hits_bytes = 0;
232 pool->alloc_total = 0;
247 sfpool_t *pool = (sfpool_t*)opaque;
249 if (size <= pool->block_size
250 && pool->free_list != NULL) {
253 pool->hits_bytes+=size;
254 pool->alloc_total+=size;
257 uint8_t *block = pool->free_list;
258 pool->free_list = *(uint8_t **)block;
264 if(ptr == NULL) perror(
"system malloc error");
267 pool->miss_bytes+=size;
268 pool->alloc_total+=size;
284 sfpool_t *pool = (sfpool_t*)opaque;
285 if (ptr == NULL)
return;
286 if (_is_in_pool(pool,ptr)) {
288 *(uint8_t **)ptr = pool->free_list;
289 pool->free_list = (uint8_t *)ptr;
316 sfpool_t *pool = (sfpool_t*)opaque;
324 if (_is_in_pool((sfpool_t*)pool,ptr)) {
325 if (size <= pool->block_size) {
328 pool->hits_bytes+=size;
329 pool->alloc_total+=size;
333 void *new_ptr = malloc(size);
334 memcpy(new_ptr, ptr, pool->block_size);
339 *(uint8_t **)ptr = pool->free_list;
340 pool->free_list = (uint8_t *)ptr;
348 pool->miss_bytes+=size;
349 pool->alloc_total+=size;
356 return realloc(ptr, size);
359 pool->miss_bytes+=size;
360 pool->alloc_total+=size;
378 sfpool_t *pool = (sfpool_t*)opaque;
380 if( _is_in_pool(pool,ptr) ) res = 1;
394 fprintf(stderr,
"\nš sfpool: %u blocks %u B each\n",
395 p->total_blocks, p->block_size);
397 fprintf(stderr,
"š Total: %lu K\n",
398 p->alloc_total/1024);
399 fprintf(stderr,
"š Misses: %lu K (%u calls)\n",p->miss_bytes/1024,p->miss_total);
400 fprintf(stderr,
"š Hits: %lu K (%u calls)\n",p->hits_bytes/1024,p->hits_total);
size_t sfpool_init(sfpool_t *pool, size_t nmemb, size_t blocksize)
Initializes a memory pool.
Definition sfpool.h:186
int sfpool_contains(void *restrict opaque, const void *ptr)
Checks if a pointer is within the memory pool.
Definition sfpool.h:377
void sfpool_status(sfpool_t *restrict p)
Prints the status of the memory pool.
Definition sfpool.h:393
void sfpool_teardown(sfpool_t *restrict pool)
Tears down a memory pool.
Definition sfpool.h:226
void * sfpool_realloc(void *restrict opaque, void *ptr, const size_t size)
Reallocates memory from the pool.
Definition sfpool.h:315
void sfpool_free(void *restrict opaque, void *ptr)
Frees memory allocated from the pool.
Definition sfpool.h:283
void * sfpool_malloc(void *restrict opaque, const size_t size)
Allocates memory from the pool.
Definition sfpool.h:246
void sfutil_zero(void *ptr, uint32_t size)
Zeroes out a block of memory.
Definition sfpool.h:99
void sfutil_secfree(void *ptr, size_t size)
Frees memory allocated securely.
Definition sfpool.h:157
void * sfutil_secalloc(size_t size)
Allocates memory securely.
Definition sfpool.h:127
void * sfutil_memalign(const void *ptr)
Aligns a pointer to the nearest boundary.
Definition sfpool.h:113