XenevaOS
Loading...
Searching...
No Matches
tlsf.h
Go to the documentation of this file.
1
29#ifndef _TLSF_H_
30#define _TLSF_H_
31
32#include <stdint.h>
33#include <stddef.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39/* ---- TLSF configuration ---- */
40#define TLSF_ALIGN_SIZE 16
41#define TLSF_ALIGN_MASK (TLSF_ALIGN_SIZE - 1)
42#define TLSF_ALIGN_UP(x) (((x) + TLSF_ALIGN_MASK) & ~TLSF_ALIGN_MASK)
43
44/* Two-level bitmap parameters */
45#define SL_INDEX_COUNT_LOG2 5
46#define SL_INDEX_COUNT (1U << SL_INDEX_COUNT_LOG2) /* 32 */
47#define SL_INDEX_MASK (SL_INDEX_COUNT - 1)
48
49/* First-level bitmap: one bit per power-of-two range */
50#define FL_INDEX_COUNT (8 * sizeof(size_t))
51
52/* ---- Block header layout ---- */
53/* Block header: 2 × size_t = 16 bytes on 64-bit.
54 * This gives 16-byte alignment for the user payload
55 * (payload starts at block_start + 16, which is 16-aligned
56 * when block_start itself is 16-aligned).
57 */
58#define BLOCK_FLAG_FREE 0x1U
59#define BLOCK_FLAG_PREV_FREE 0x2U
60#define BLOCK_SIZE_MASK (~(size_t)(BLOCK_FLAG_FREE | BLOCK_FLAG_PREV_FREE))
61
62typedef struct block_header {
63 size_t size; /* bit 0 = free, bit 1 = prev-free; rest = block size (incl. header) */
64 size_t prev_size; /* size of the previous physical block (for O(1) backward coalescing) */
66
67/* Free block: header (16) + doubly-linked-list pointers (16) = 32 bytes minimum.
68 * The payload of a free block starts at offset 16 (= next_free pointer).
69 */
75
76/* Sizes */
77#define TLSF_HEADER_SIZE ((size_t)sizeof(block_header_t)) /* 16 */
78#define TLSF_FREE_BLOCK_SIZE ((size_t)sizeof(free_block_t)) /* 32 */
79#define TLSF_MIN_BLOCK_SIZE TLSF_FREE_BLOCK_SIZE /* 32 — minimum free block */
80#define TLSF_SENTINEL_SIZE TLSF_HEADER_SIZE /* 16 — sentinel block */
81
82/* ---- TLSF pool / control structure ---- */
90
91/* ---- Public API ---- */
92
93/* Initialize a TLSF pool. Returns a pointer to a static pool, or NULL on failure. */
95
96/* Return the current global pool (for internal use). */
98
99/* Add a contiguous memory region to the pool.
100 * Returns 0 on success, -1 on failure.
101 */
102int tlsf_add_memory(tlsf_pool_t *pool, void *mem, size_t size);
103
104/* Allocate `size` bytes of 16-byte-aligned memory.
105 * Returns NULL when the pool is exhausted (caller should grow the pool).
106 */
107void *tlsf_malloc(tlsf_pool_t *pool, size_t size);
108
109/* Free a previously-allocated block. */
110void tlsf_free(tlsf_pool_t *pool, void *ptr);
111
112/* Resize an allocation (in-place shrink / grow-or-move). */
113void *tlsf_realloc(tlsf_pool_t *pool, void *ptr, size_t size);
114
115/* Statistics */
116static inline size_t tlsf_used(tlsf_pool_t *pool) { return pool ? pool->used_size : 0; }
117static inline size_t tlsf_total(tlsf_pool_t *pool) { return pool ? pool->pool_size : 0; }
118
119#ifdef __XENEVA_DEBUG_ALLOC__
120/* ---- Stage 2: debug-only block layout ----
121 * Live block: [tlsf hdr 16][dbg hdr 16][front RZ 16][user N][back RZ 16].
122 * The user pointer stays 16-aligned (48 = 3 x 16). Free blocks keep the
123 * stock layout; all translation happens at the API boundary, so every
124 * internal helper (coalescing, buckets, walking) is untouched.
125 * Everything in this block vanishes when the flag is off. */
126#define TLSF_RZ_SIZE 16
127#define TLSF_RZ_PATTERN 0xFCu
128#define TLSF_POISON_FREE 0x6Bu
129#define TLSF_POISON_FRESH 0xAAu
130#define TLSF_DBG_HDR_SIZE ((size_t)sizeof(tlsf_dbg_hdr_t))
131#define TLSF_DBG_OVERHEAD (TLSF_DBG_HDR_SIZE + 2 * TLSF_RZ_SIZE)
132
133typedef struct tlsf_dbg_hdr {
134 void *caller; /* __builtin_return_address(1): kmalloc's caller */
135 uint32_t seq; /* allocation sequence number */
136 uint32_t user_size; /* requested payload bytes (RZ/poison bounds) */
137} tlsf_dbg_hdr_t;
138
139/* Walk every region grafted into the pool, group live blocks by caller,
140 * print the top offenders. Read-only; caller must hold the heap lock. */
141void tlsf_leak_dump(tlsf_pool_t *pool);
142
143/* Initialise a caller-provided pool object, independent of the global
144 * pool. Used by the debug self-tests so deliberate corruption never
145 * touches the live heap. */
146tlsf_pool_t *tlsf_create_at(tlsf_pool_t *pool);
147
148/* Cumulative detector reports (redzone / poison / double-free). Tests
149 * assert this moves; operators watch it via the debugger. */
150uint64_t tlsf_dbg_violation_count(void);
151
152/* Caller hint side-channel (see tlsf.c): the public wrappers stash
153 * their own return address (frame 0: always safe) before entering the
154 * backend, which stamps it into the block. No signature changes. */
155void tlsf_dbg_hint_set(void *caller);
156#endif /* __XENEVA_DEBUG_ALLOC__ */
157
158#ifdef __cplusplus
159}
160#endif
161
162#endif /* _TLSF_H_ */
unsigned int uint32_t
Definition acefiex.h:163
COMPILER_DEPENDENT_UINT64 uint64_t
Definition acefiex.h:165
size_t size
Definition drm_bridge.h:1299
Definition tlsf.h:62
size_t size
Definition tlsf.h:63
size_t prev_size
Definition tlsf.h:64
Definition tlsf.h:70
struct free_block * next_free
Definition tlsf.h:72
struct free_block * prev_free
Definition tlsf.h:73
block_header_t hdr
Definition tlsf.h:71
Definition tlsf.h:83
uint64_t fl_bitmap
Definition tlsf.h:84
size_t pool_size
Definition tlsf.h:87
free_block_t * blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]
Definition tlsf.h:86
size_t used_size
Definition tlsf.h:88
uint32_t sl_bitmap[FL_INDEX_COUNT]
Definition tlsf.h:85
#define SL_INDEX_COUNT
Definition tlsf.h:46
tlsf_pool_t * tlsf_get_pool(void)
Definition tlsf.c:48
int tlsf_add_memory(tlsf_pool_t *pool, void *mem, size_t size)
Definition tlsf.c:358
tlsf_pool_t * tlsf_create(void)
Definition tlsf.c:351
struct free_block free_block_t
struct block_header block_header_t
void * tlsf_malloc(tlsf_pool_t *pool, size_t size)
Definition tlsf.c:411
void * tlsf_realloc(tlsf_pool_t *pool, void *ptr, size_t size)
Definition tlsf.c:644
void tlsf_free(tlsf_pool_t *pool, void *ptr)
Definition tlsf.c:522
#define FL_INDEX_COUNT
Definition tlsf.h:50
struct tlsf_pool tlsf_pool_t