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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#ifndef MLIB_ALLOC_H
#define MLIB_ALLOC_H
#include "_allocator.h"
#include "_attrs.h"
typedef enum {
ALLOC_OOM,
} alloc_err_t;
typedef struct arena_blk arena_blk_t;
typedef struct {
ptrdiff_t blksz;
struct arena_blk *_head;
} arena_ctx_t;
typedef struct {
void *buf;
ptrdiff_t len;
} st_buf_t;
#define new(mem, T, n) \
((typeof(T) *)((mem).alloc((mem), \
ALLOC_NEW, \
nullptr, \
0, \
(n), \
sizeof(T), \
alignof(T))))
#define resz(mem, p, o, n) \
((typeof(p))((mem).alloc((mem), \
ALLOC_RESIZE, \
(p), \
(o), \
(n), \
sizeof(*(p)), \
alignof(typeof(*(p))))))
#define delete(mem, p, sz) \
(mem).alloc((mem), \
ALLOC_FREE, \
(p), \
(sz), \
0, \
sizeof(*(p)), \
alignof(typeof(*p)))
#define deleteall(mem) \
((mem).alloc((mem), \
ALLOC_FREEALL, \
nullptr, \
0, \
0, \
0, \
0))
void *arena_alloc(allocator_t mem, alloc_mode_t mode, void *ptr,
ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz,
ptrdiff_t align);
void *heap_alloc(allocator_t mem, alloc_mode_t mode, void *ptr,
ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz,
ptrdiff_t align);
void *static_scratch_alloc(allocator_t mem, alloc_mode_t mode, void *ptr,
ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz,
ptrdiff_t align);
[[_mlib_inline]] static inline allocator_t
init_arena_allocator(arena_ctx_t *ctx, jmp_buf *jmp)
{
return (allocator_t){
.alloc = arena_alloc,
.err = jmp,
.ctx = ctx,
};
}
[[_mlib_inline]] static inline allocator_t
init_heap_allocator(jmp_buf *jmp)
{
return (allocator_t){
.alloc = heap_alloc,
.err = jmp,
};
}
[[_mlib_inline]] static inline allocator_t
init_static_scratch_allocator(st_buf_t *ctx, jmp_buf *jmp)
{
return (allocator_t){
.alloc = static_scratch_alloc,
.err = jmp,
.ctx = ctx,
};
}
#endif /* !MLIB_ALLOC_H */
|