summaryrefslogtreecommitdiff
path: root/freelist.h
blob: 6a642d72932d19a97bedb45998394a9eeb5fc2ba (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
#ifndef FREELIST_H
#define FREELIST_H

#include "arena.h"
#include <string.h>

#define FREELIST_NEW(fl, a)\
    (__typeof__(*(fl)))freelist_new((void**)(fl), sizeof(**(fl)), _Alignof(__typeof__(**(fl))), a)

#define FREELIST_FREE(fl, p)\
    freelist_free((void **)(fl), (void *)(p))

static inline void *freelist_new(void **fl, size_t sz, size_t align, Arena *a) {
	if (*fl) {
		void *p = *fl;
		void *next = *(void**)p;
		*fl = next;
		return memset(p, 0, sz);
	} else {
		/* must pad and align for ptr to next in freelist */
		if (sz    < sizeof(void *))   sz    = sizeof(void *);
		if (align < _Alignof(void *)) align = _Alignof(void *);
		return arena_alloc(a, sz, align);
	}
}

static inline void freelist_free(void **fl, void *p) {
	*(void **)p = *fl;
	*fl = p;
}

#endif