detalloc: Deterministic Real-Time Allocator $PROJECT_NUMBER
C99 constant-time pool allocator for hard real-time
Loading...
Searching...
No Matches
detalloc.h
Go to the documentation of this file.
1/**
2 * @file detalloc.h
3 * @brief Detalloc — Phase 1: Single-Pool, Constant-Time Allocator
4 *
5 * Minimal API for a fixed-size, bitmap-based pool allocator with O(1)
6 * alloc/free. Designed for hard real-time use; no syscalls after init; uses
7 * user-provided memory.
8 *
9 * @version 0.1.0
10 * @date 2025
11 */
12
13#ifndef DETALLOC_H
14#define DETALLOC_H
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20/* ========================================================================== */
21/* Includes */
22/* ========================================================================== */
23#include <stdbool.h>
24#include <stddef.h>
25#include <stdint.h>
26
27/* ========================================================================== */
28/* Visibility / Inline */
29/* ========================================================================== */
30/**
31 * @def DETALLOC_API
32 * @brief Export/import macro for building/using shared libraries.
33 */
34#ifndef DETALLOC_API
35#if defined(_WIN32) && !defined(__GNUC__)
36#ifdef DETALLOC_BUILD
37#define DETALLOC_API __declspec(dllexport)
38#else
39#define DETALLOC_API __declspec(dllimport)
40#endif
41#else
42#define DETALLOC_API __attribute__((visibility("default")))
43#endif
44#endif
45
46/**
47 * @def DET_INLINE
48 * @brief Always-inline helper for hot-path functions where supported.
49 */
50#ifndef DET_INLINE
51#if defined(__GNUC__) || defined(__clang__)
52#define DET_INLINE static inline __attribute__((always_inline))
53#else
54#define DET_INLINE static inline
55#endif
56#endif
57
58/* ========================================================================== */
59/* Version */
60/* ========================================================================== */
61#define DETALLOC_VERSION_MAJOR 0
62#define DETALLOC_VERSION_MINOR 1
63#define DETALLOC_VERSION_PATCH 0
64
65/* ========================================================================== */
66/* Defaults & Align */
67/* ========================================================================== */
68/** Default block size for Phase 1 (can be overridden at init-time). */
69#ifndef DET_DEFAULT_BLOCK_SIZE
70#define DET_DEFAULT_BLOCK_SIZE 64
71#endif
72
73/** Default alignment for returned blocks (power of two). */
74#ifndef DET_DEFAULT_ALIGN
75#define DET_DEFAULT_ALIGN 8
76#endif
77
78/** Align up helper. */
79#ifndef DET_ALIGN_UP
80#define DET_ALIGN_UP(sz, a) (((sz) + ((a)-1)) & ~((a)-1))
81#endif
82
83/* ========================================================================== */
84/* Error Codes */
85/* ========================================================================== */
86/**
87 * @brief Error/status codes returned by Detalloc.
88 */
89typedef enum {
90 DET_OK = 0, /**< Operation successful */
91 DET_ERR_INVALID_PARAM, /**< A parameter is invalid */
92 DET_ERR_OUT_OF_MEMORY, /**< Buffer cannot accommodate configuration */
93 DET_ERR_POOL_FULL, /**< Pool has no free blocks */
94 DET_ERR_INVALID_PTR, /**< Pointer not owned by allocator/pool */
95 DET_ERR_NOT_INITIALIZED /**< Allocator not initialized */
97
98/* ========================================================================== */
99/* Opaque Handle */
100/* ========================================================================== */
101/**
102 * @brief Opaque allocator handle (single pool in Phase 1).
103 *
104 * Implementation maintains:
105 * - user buffer base/limit
106 * - bitmap for free/used slots
107 * - fixed block size & count
108 * - optional lock if thread_safe=true
109 */
110typedef struct det_allocator det_allocator_t;
111
112/* ========================================================================== */
113/* Configuration (Phase 1) */
114/* ========================================================================== */
115/**
116 * @brief Phase-1 configuration: one fixed-size pool.
117 */
118typedef struct {
119 size_t block_size; /**< Size of each block in bytes (e.g., 64). */
120 size_t num_blocks; /**< Number of blocks in the pool. */
121 size_t align; /**< Alignment for allocations (default DET_DEFAULT_ALIGN). */
122 bool thread_safe; /**< Optional: enable internal locking (constant-time). */
124
125/* ========================================================================== */
126/* Core API */
127/* ========================================================================== */
128/**
129 * @brief Compute required buffer size for a given Phase-1 config.
130 *
131 * Calculates metadata + bitmap + aligned payload area.
132 *
133 * @param config Non-NULL configuration
134 * @return Required bytes, or 0 on error
135 *
136 * @par Complexity
137 * O(1).
138 */
139DETALLOC_API size_t det_alloc_size(const det_config_t *config);
140
141/**
142 * @brief Initialize allocator over a user-provided memory buffer.
143 *
144 * No dynamic allocation; all metadata lives inside @p memory.
145 *
146 * @param memory Pointer to pre-allocated memory buffer (non-NULL)
147 * @param size Size of memory buffer in bytes (>= det_alloc_size(config))
148 * @param config Non-NULL Phase-1 configuration
149 * @return Allocator handle on success, or NULL on error
150 *
151 * @note The buffer must remain valid for the allocator lifetime.
152 * @par Complexity
153 * O(1).
154 */
155DETALLOC_API det_allocator_t *det_alloc_init(void *memory, size_t size,
156 const det_config_t *config);
157
158/**
159 * @brief Allocate a single fixed-size block.
160 *
161 * @param alloc Allocator handle
162 * @return Pointer to block on success, or NULL if pool is full
163 *
164 * @note Returned pointer is aligned to config.align.
165 * @par Complexity
166 * O(1) worst-case.
167 */
168DETALLOC_API void *det_alloc(det_allocator_t *alloc);
169
170/**
171 * @brief Allocate a zero-initialized block.
172 *
173 * @param alloc Allocator handle
174 * @return Pointer to zeroed block, or NULL if pool is full
175 *
176 * @par Complexity
177 * O(block_size) for zeroing, O(1) for allocation.
178 */
179DETALLOC_API void *det_calloc(det_allocator_t *alloc);
180
181/**
182 * @brief Free a previously allocated block (NULL is a no-op).
183 *
184 * @param alloc Allocator handle
185 * @param ptr Pointer returned by det_alloc()/det_calloc()
186 *
187 * @warning Undefined behavior if @p ptr was not allocated by this allocator.
188 * @par Complexity
189 * O(1) worst-case.
190 */
191DETALLOC_API void det_free(det_allocator_t *alloc, void *ptr);
192
193/**
194 * @brief Return usable size of a block.
195 *
196 * @param alloc Allocator handle
197 * @param ptr Pointer to allocated block
198 * @return Fixed block size (or 0 if invalid)
199 *
200 * @par Complexity
201 * O(1).
202 */
203DETALLOC_API size_t det_alloc_usable_size(det_allocator_t *alloc, void *ptr);
204
205/**
206 * @brief Destroy allocator structures (metadata cleanup only).
207 *
208 * The user-provided memory buffer is **not** freed.
209 *
210 * @param alloc Allocator handle
211 *
212 * @par Complexity
213 * O(1).
214 */
215DETALLOC_API void det_alloc_destroy(det_allocator_t *alloc);
216
217/* ========================================================================== */
218/* Convenience */
219/* ========================================================================== */
220/**
221 * @brief Return a sensible Phase-1 default config.
222 *
223 * Defaults:
224 * - block_size = DET_DEFAULT_BLOCK_SIZE
225 * - num_blocks = 0 (must be set by user)
226 * - align = DET_DEFAULT_ALIGN
227 * - thread_safe = false
228 */
229DETALLOC_API det_config_t det_default_config(void);
230
231/**
232 * @brief Get library version string "major.minor.patch".
233 */
234DETALLOC_API const char *det_version_string(void);
235
236/* ========================================================================== */
237/* Macros */
238/* ========================================================================== */
239/** Allocate a typed object (one fixed-size block must fit it). */
240#define DET_NEW(alloc, type) ((type *)det_alloc((alloc)))
241
242/** Free and null a pointer. */
243#define DET_FREE(alloc, ptr) \
244 do { \
245 det_free((alloc), (ptr)); \
246 (ptr) = NULL; \
247 } while (0)
248
249#ifdef __cplusplus
250} /* extern "C" */
251#endif
252#endif /* DETALLOC_H */
struct det_allocator det_allocator_t
Opaque allocator handle (single pool in Phase 1).
Definition detalloc.h:110
det_error_t
Error/status codes returned by Detalloc.
Definition detalloc.h:89
@ DET_OK
Definition detalloc.h:90
@ DET_ERR_POOL_FULL
Definition detalloc.h:93
@ DET_ERR_OUT_OF_MEMORY
Definition detalloc.h:92
@ DET_ERR_INVALID_PARAM
Definition detalloc.h:91
@ DET_ERR_INVALID_PTR
Definition detalloc.h:94
@ DET_ERR_NOT_INITIALIZED
Definition detalloc.h:95
DETALLOC_API void * det_alloc(det_allocator_t *alloc)
Allocate a single fixed-size block.
DETALLOC_API det_allocator_t * det_alloc_init(void *memory, size_t size, const det_config_t *config)
Initialize allocator over a user-provided memory buffer.
DETALLOC_API size_t det_alloc_size(const det_config_t *config)
Compute required buffer size for a given Phase-1 config.
DETALLOC_API det_config_t det_default_config(void)
Return a sensible Phase-1 default config.
Definition detalloc.c:5
DETALLOC_API const char * det_version_string(void)
Get library version string "major.minor.patch".
Definition detalloc.c:3
DETALLOC_API void det_alloc_destroy(det_allocator_t *alloc)
Destroy allocator structures (metadata cleanup only).
DETALLOC_API size_t det_alloc_usable_size(det_allocator_t *alloc, void *ptr)
Return usable size of a block.
DETALLOC_API void det_free(det_allocator_t *alloc, void *ptr)
Free a previously allocated block (NULL is a no-op).
DETALLOC_API void * det_calloc(det_allocator_t *alloc)
Allocate a zero-initialized block.
Phase-1 configuration: one fixed-size pool.
Definition detalloc.h:118
bool thread_safe
Definition detalloc.h:122
size_t num_blocks
Definition detalloc.h:120
size_t block_size
Definition detalloc.h:119
size_t align
Definition detalloc.h:121