summaryrefslogtreecommitdiff
path: root/malloc/my_recycler/recycler.c
blob: f2e7da5eba046d9291d74f66cf84b27a3769d6ed (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
#include "recycler.h"

#include <stdlib.h>

struct recycler *recycler_create(size_t block_size, size_t total_size)
{
    if (block_size % sizeof(size_t) || !block_size || !total_size
        || total_size % block_size)
        return NULL;
    struct recycler *rec = malloc(sizeof(struct recycler));
    if (rec == NULL)
        return NULL;
    rec->block_size = block_size;
    rec->capacity = total_size / block_size;
    rec->chunk = malloc(total_size * sizeof(void *));
    if (rec->chunk == NULL)
    {
        free(rec);
        return NULL;
    }
    rec->free = rec->chunk;
    struct free_list *f = rec->free;
    for (size_t i = 0; i < rec->capacity - 1; i++)
    {
        f->next = f + block_size;
        f = f->next;
    }

    f->next = NULL;

    return rec;
}

void recycler_destroy(struct recycler *r)
{
    if (r == NULL)
        return;
    free(r->chunk);
    free(r);
}

void *recycler_allocate(struct recycler *r)
{
    if (r == NULL || r->free == NULL)
        return NULL;

    void *res = r->free;
    struct free_list *f = r->free;
    r->free = f->next;
    return res;
}

void recycler_free(struct recycler *r, void *block)
{
    if (r == NULL || block == NULL)
        return;

    struct free_list *old_head = r->free;
    r->free = block;
    struct free_list *b = block;
    b->next = old_head;
}