summaryrefslogtreecommitdiff
path: root/deps/nmx_pool/mempool.c
blob: d87c651230d7ac7d4a180ea9184ae6c930f421be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "mempool.h"
#include "nmx_palloc.h"

typedef struct mem_block {
    size_t size;
    struct mem_block *next;
} mem_block_t;

struct mem_pool_s{
    mem_block_t *free_list;
    nmx_pool_t *pool;
    size_t pool_size;
} ;

mem_pool_t *create_mem_pool(size_t pool_size) {
    mem_pool_t *mem_pool = (mem_pool_t *)malloc(sizeof(mem_pool_t));
    mem_pool->pool = nmx_create_pool(pool_size);
    mem_pool->free_list = NULL;
    mem_pool->pool_size = pool_size;
    return mem_pool;
}

void *mem_alloc(mem_pool_t *mem_pool, size_t size) {
    mem_block_t *prev = NULL;
    mem_block_t *current = mem_pool->free_list;

    // find free block
    while (current != NULL) {
        if (current->size >= size) {
            if (prev != NULL) {
                prev->next = current->next;
            } else {
                mem_pool->free_list = current->next;
            }
            return (void *)(current + 1);
        }
        prev = current;
        current = current->next;
    }

    // no suitable free block, allocate new block
    mem_block_t *new_block = (mem_block_t *)nmx_palloc(mem_pool->pool, sizeof(mem_block_t) + size);
    if (new_block == NULL) {
        return NULL;
    }
    new_block->size = size;
    return (void *)(new_block + 1);
}

void mem_free(mem_pool_t *mem_pool, void *ptr) {
    if (ptr == NULL) {
        return;
    }
    //try free lagre block
    if(nmx_pfree(mem_pool->pool, ptr)) {
        return;
    }
    mem_block_t *block = (mem_block_t *)ptr - 1;
    block->next = mem_pool->free_list;
    mem_pool->free_list = block;
}

void destroy_mem_pool(mem_pool_t *mem_pool) {
    nmx_destroy_pool(mem_pool->pool);
    free(mem_pool);
}