-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathspaces.h
More file actions
310 lines (266 loc) · 10.7 KB
/
spaces.h
File metadata and controls
310 lines (266 loc) · 10.7 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/* spaces.h — public API for the Spaces allocator.
*
* Copyright (c) 2021-2026 Praveen Vaddadi <thynktank@gmail.com>
* Released under the MIT License. See LICENSE for details.
*/
#ifndef SPACES_H
#define SPACES_H
#include <stddef.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ================================================================
* Types
* ================================================================ */
typedef unsigned long SpacesThreadId;
typedef unsigned SpacesVersion;
typedef struct _SPACESIChunk *SpacesChunk;
typedef enum {
SPACES_OK = 0,
SPACES_ERR_INTERNAL,
SPACES_ERR_OUT_OF_MEMORY,
SPACES_ERR_BLOCK_TOO_BIG,
SPACES_ERR_ALLOC_ZERO,
SPACES_ERR_RESIZE_FAILED,
SPACES_ERR_LOCK,
SPACES_ERR_EXCEEDED_CEILING,
SPACES_ERR_TOO_MANY_PAGES,
SPACES_ERR_TOO_MANY_TASKS,
SPACES_ERR_BAD_CHUNK,
SPACES_ERR_BAD_BLOCK,
SPACES_ERR_BAD_FREE_BLOCK,
SPACES_ERR_BAD_POINTER,
SPACES_ERR_WRONG_TASK,
SPACES_ERR_NOT_FIXED_SIZE,
SPACES_ERR_BAD_FLAGS,
SPACES_ERR_UNSUPPORTED,
SPACES_ERR_EXCEEDED_HEAP_LIMIT,
SPACES_ERR_LICENSE,
SPACES_ERR_BAD_ALIGNMENT,
SPACES_ERR_CODE_COUNT,
SPACES_ERR_INT_MAX = INT_MAX
} SpacesErrorCode;
typedef enum {
SPACES_BLOCK_FIXED = 0x0001u,
SPACES_BLOCK_VAR_MOVEABLE = 0x0002u,
SPACES_BLOCK_VAR_FIXED = 0x0004u,
SPACES_BLOCK_EXTERNAL = 0x0008u,
SPACES_BLOCK_FREE = 0x0010u,
SPACES_BLOCK_INT_MAX = INT_MAX
} SpacesBlockType;
typedef enum {
SPACES_SMALL_NONE,
SPACES_SMALL_V3,
SPACES_SMALL_V5,
SPACES_SMALL_INT_MAX = INT_MAX
} SpacesSmallAllocator;
typedef enum {
SPACES_CHUNK_OK = 1,
SPACES_CHUNK_CORRUPT = -1,
SPACES_CHUNK_CORRUPT_FATAL = -2,
SPACES_CHUNK_END = 0,
SPACES_CHUNK_STATUS_MAX = INT_MAX
} SpacesChunkStatus;
typedef enum {
SPACES_PTR_OK = 1,
SPACES_PTR_WILD = 0,
SPACES_PTR_FREE = -1,
SPACES_PTR_STATUS_MAX = INT_MAX
} SpacesPointerStatus;
typedef enum {
SPACES_THREAD_EXCLUSIVE_OFF = 0,
SPACES_THREAD_EXCLUSIVE_ON = 0x10000u,
SPACES_FREE_ON_THREAD_TERM = 0x20000u
} SpacesThreadExclusive;
/* Error info structure */
typedef struct _SpacesErrorInfo {
SpacesErrorCode errorCode;
SpacesChunk chunk;
SpacesChunk argChunk;
void *argPtr;
void *argBuf;
size_t argSize;
size_t argCount;
unsigned argFlags;
const char *file;
int line;
unsigned long allocCount;
unsigned long passCount;
unsigned checkpoint;
void *errorAlloc;
void *corruptAddr;
struct _SpacesErrorInfo *objectCreationInfo;
SpacesThreadId threadID;
unsigned long pid;
void *callStack[32];
} SpacesErrorInfo;
typedef int (*SpacesErrorFn)(SpacesErrorInfo *);
/* Chunk walk entry */
typedef struct {
void *entry;
SpacesChunk chunk;
SpacesBlockType type;
int isInUse;
size_t size;
unsigned lockCount;
void *reserved_ptr;
SpacesChunk reserved_chunk;
} SpacesChunkEntry;
/* Chunk info */
typedef struct {
SpacesChunk chunk;
SpacesBlockType type;
unsigned short blockSizeFS;
unsigned short smallBlockSize;
unsigned pageSize;
size_t floor;
size_t ceiling;
unsigned flags;
SpacesErrorFn errorFn;
} SpacesChunkInfo;
/* Process info */
typedef struct {
size_t growIncrement;
size_t freeBytes;
size_t largeBlockThreshold;
size_t heapLimit;
size_t heapTotal;
size_t totalFree;
int useMunmap;
int coelesceSystemAllocs;
} SpacesProcessInfo;
/* ================================================================
* Allocation flags
* ================================================================ */
#define SPACES_FLAG_FIXED 0x0000u
#define SPACES_FLAG_ZERO_INIT 0x0001u
#define SPACES_FLAG_MOVEABLE 0x0002u
#define SPACES_FLAG_RESIZEABLE 0x0004u
#define SPACES_FLAG_RESIZE_IN_PLACE 0x0008u
#define SPACES_FLAG_NO_GROW 0x0010u
#define SPACES_FLAG_NO_EXTERNAL 0x0020u
#define SPACES_FLAG_NO_COMPACT 0x0040u
#define SPACES_FLAG_NO_SERIALIZE 0x0080u
/* Chunk creation flags */
#define SPACES_CHUNK_SHARED 0x0001u
#define SPACES_CHUNK_SERIALIZE 0x0002u
#define SPACES_CHUNK_VIRTUAL_LOCK 0x0004u
#define SPACES_CHUNK_ZERO_INIT 0x0008u
#define SPACES_CHUNK_AREA 0x0010u
#define SPACES_CHUNK_FILE_MAPPING 0x0020u
#define SPACES_CHUNK_DEFAULT 0x8000u
#define SPACES_ERROR_RET ((size_t)(-1))
#define SPACES_UNLOCK_FAILED USHRT_MAX
#define SPACES_MAX_CALL_STACK 32
/* ================================================================
* Default chunk globals
* ================================================================ */
extern SpacesChunk spaces_default_chunk;
extern unsigned short spaces_default_block_size;
extern unsigned spaces_default_page_size;
extern unsigned spaces_default_flags;
extern int spaces_malloc_linked;
/* ================================================================
* Core allocator
* ================================================================ */
void spaces_core_init(void);
void *spaces_malloc(size_t size);
void spaces_free(void *ptr);
void *spaces_calloc(size_t nobj, size_t size);
void *spaces_realloc(void *ptr, size_t size);
void *spaces_memalign(size_t alignment, size_t size);
size_t spaces_usable_size(void *ptr);
void spaces_thread_cleanup(void);
/* ================================================================
* Initialization / shutdown
* ================================================================ */
int spaces_init(void);
int spaces_shutdown(void);
SpacesVersion spaces_version(void);
SpacesChunk spaces_init_default_chunk(void);
int spaces_free_default_chunk(void);
int spaces_default_chunk_thread_exclusive(unsigned flags);
/* ================================================================
* Chunk lifecycle
* ================================================================ */
SpacesChunk spaces_chunk_create(unsigned flags);
SpacesChunk spaces_chunk_create_fixed(unsigned short block_size, size_t count, unsigned flags);
SpacesChunk spaces_chunk_create_area(void *addr, size_t size, unsigned flags);
SpacesChunk spaces_chunk_create_area_ex(void *addr, size_t size, unsigned flags, void *security);
SpacesChunk spaces_chunk_create_shared(const char *name, size_t size, unsigned flags);
SpacesChunk spaces_chunk_attach_shared(SpacesChunk chunk, const char *name);
int spaces_chunk_destroy(SpacesChunk chunk);
/* ================================================================
* Chunk allocation
* ================================================================ */
void *spaces_chunk_alloc(SpacesChunk chunk, size_t size, unsigned flags);
void *spaces_chunk_alloc_fixed(SpacesChunk chunk);
void *spaces_chunk_alloc_aligned(SpacesChunk chunk, size_t size, size_t alignment, unsigned flags);
void *spaces_chunk_alloc_aligned_offset(SpacesChunk chunk, size_t size, size_t alignment, size_t offset, unsigned flags);
int spaces_chunk_free(void *ptr);
int spaces_chunk_free_fixed(void *ptr);
int spaces_chunk_free_aligned(void *ptr);
void *spaces_chunk_realloc(void *ptr, size_t size, unsigned flags);
void *spaces_chunk_realloc_aligned(void *ptr, size_t size, size_t alignment, unsigned flags);
void *spaces_chunk_realloc_aligned_offset(void *ptr, size_t size, size_t alignment, size_t offset, unsigned flags);
size_t spaces_chunk_ptr_size(void *ptr);
size_t spaces_chunk_size_aligned(void *ptr);
SpacesPointerStatus spaces_chunk_ptr_check(SpacesChunk chunk, void *ptr);
SpacesChunkStatus spaces_chunk_check_aligned(SpacesChunk chunk, void *ptr);
/* ================================================================
* Chunk configuration
* ================================================================ */
unsigned spaces_chunk_set_page_size(SpacesChunk chunk, unsigned size);
int spaces_chunk_set_block_size(SpacesChunk chunk, unsigned short size);
int spaces_chunk_set_small_allocator(SpacesChunk chunk, SpacesSmallAllocator alg);
int spaces_chunk_set_small_block_size(SpacesChunk chunk, unsigned short size);
size_t spaces_chunk_set_floor(SpacesChunk chunk, size_t floor);
size_t spaces_chunk_set_ceiling(SpacesChunk chunk, size_t ceiling);
size_t spaces_chunk_set_free_bytes(SpacesChunk chunk, size_t bytes);
size_t spaces_chunk_set_grow_increment(SpacesChunk chunk, size_t inc);
unsigned spaces_chunk_set_max_suballoc(SpacesChunk chunk, unsigned size);
int spaces_chunk_set_max_subchunks(SpacesChunk chunk, unsigned count);
int spaces_chunk_set_serialization(SpacesChunk chunk, int enable);
int spaces_chunk_set_page_resizing(SpacesChunk chunk, int enable);
/* ================================================================
* Chunk inspection
* ================================================================ */
size_t spaces_chunk_preallocate(SpacesChunk chunk, size_t bytes, SpacesBlockType type);
size_t spaces_chunk_shrink(SpacesChunk chunk);
size_t spaces_chunk_size(SpacesChunk chunk);
size_t spaces_chunk_count(SpacesChunk chunk);
int spaces_chunk_info(SpacesChunk chunk, void *ptr, SpacesChunkInfo *info);
SpacesChunkStatus spaces_chunk_first(SpacesChunkInfo *info, int all_tasks);
SpacesChunkStatus spaces_chunk_next(SpacesChunkInfo *info, int all_tasks);
SpacesChunkStatus spaces_chunk_walk(SpacesChunk chunk, SpacesChunkEntry *entry);
int spaces_chunk_check(SpacesChunk chunk);
int spaces_chunk_lock(SpacesChunk chunk);
int spaces_chunk_unlock(SpacesChunk chunk);
/* ================================================================
* Error handling
* ================================================================ */
SpacesErrorFn spaces_set_error_handler(SpacesErrorFn fn);
int spaces_default_error_handler(SpacesErrorInfo *err);
void spaces_error_unwind(void);
/* ================================================================
* Process configuration
* ================================================================ */
int spaces_process_info(SpacesProcessInfo *info);
size_t spaces_process_set_grow_increment(size_t size);
size_t spaces_process_set_free_bytes(size_t size);
size_t spaces_process_set_large_threshold(size_t size);
size_t spaces_process_set_heap_limit(size_t size);
int spaces_process_use_munmap(int enable);
int spaces_process_coalesce_allocs(int enable);
void spaces_process_flush_all(void);
void spaces_process_disable_fork_handlers(void);
size_t spaces_process_set_page_cache_size(int page_multiple, size_t size);
/* Deprecated / no-op */
#define spaces_chunk_set_high_threads(p, b)
/* Internal (for spacesi_bitcount used by posix_memalign validation) */
int spaces__bitcount(size_t val);
#ifdef __cplusplus
}
#endif
#endif /* SPACES_H */