1#include <stddef.h>
 2#include <stdint.h>
 3#include <stdio.h>
 4#include <stdlib.h>
 5#include <string.h>
 6
 7#include "allocator.h"
 8
 9static AllocatorStats stats = {};
10
11static void* _allocate(unsigned nbytes, bool clean)
12{
13    void* result;
14    if (clean) {
15        result = calloc(1, nbytes);
16    } else {
17        result = malloc(nbytes);
18    }
19    if (result) {
20        atomic_fetch_add(&stats.blocks_allocated, 1);
21    }
22    return result;
23}
24
25static void _release(void** addr_ptr, unsigned nbytes)
26{
27    void* addr = *addr_ptr;
28    if (addr) {
29        free(addr);
30        *addr_ptr = nullptr;
31        atomic_fetch_sub(&stats.blocks_allocated, 1);
32    }
33}
34
35static bool _reallocate(void** addr_ptr, unsigned old_nbytes, unsigned new_nbytes, bool clean, bool* addr_changed)
36{
37    if (old_nbytes == new_nbytes) {
38        goto success_same_addr;
39    }
40
41    void* addr = *addr_ptr;
42
43    // shall we allocate new addr?
44    if (addr == nullptr) {
45        if (old_nbytes != 0) {
46            goto error;
47        }
48        addr = _allocate(new_nbytes, clean);
49        if (!addr) {
50            goto error;
51        }
52        *addr_ptr = addr;
53        goto success_changed_addr;
54    }
55
56    void* new_block = realloc(addr, new_nbytes);
57    if (!new_block) {
58        goto error;
59    }
60    *addr_ptr = new_block;
61    if (addr_changed) { *addr_changed = new_block != addr; }
62    if (clean && old_nbytes < new_nbytes) {
63        memset(((uint8_t*) new_block) + old_nbytes, 0, new_nbytes - old_nbytes);
64    }
65    return true;
66
67success_changed_addr:
68    if (addr_changed) { *addr_changed = true; }
69    return true;
70
71success_same_addr:
72    if (addr_changed) { *addr_changed = false; }
73    return true;
74
75error:
76    if (addr_changed) { *addr_changed = false; }
77    return false;
78}
79
80static void _dump()
81{
82    fprintf(stderr, "Stdlib allocator: dump is not implemented\n");
83}
84
85Allocator stdlib_allocator = {
86    .init       = nullptr,
87    .allocate   = _allocate,
88    .reallocate = _reallocate,
89    .release    = _release,
90    .dump       = _dump,
91    .trace      = false,
92    .verbose    = false,
93    .stats      = &stats
94};