UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /** 29 * @file allocator.h 30 * Interface for custom allocators. 31 */ 32 33 #ifndef UCX_ALLOCATOR_H 34 #define UCX_ALLOCATOR_H 35 36 #include "common.h" 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * The class definition for an allocator. 44 */ 45 typedef struct { 46 /** 47 * The allocator's malloc() implementation. 48 */ 49 void *(*malloc)( 50 void *data, 51 size_t n 52 ); 53 54 /** 55 * The allocator's realloc() implementation. 56 */ 57 void *(*realloc)( 58 void *data, 59 void *mem, 60 size_t n 61 ); 62 63 /** 64 * The allocator's calloc() implementation. 65 */ 66 void *(*calloc)( 67 void *data, 68 size_t nmemb, 69 size_t size 70 ); 71 72 /** 73 * The allocator's free() implementation. 74 */ 75 void (*free)( 76 void *data, 77 void *mem 78 ); 79 } cx_allocator_class; 80 81 /** 82 * Structure holding the data for an allocator. 83 */ 84 struct cx_allocator_s { 85 /** 86 * A pointer to the instance of the allocator class. 87 */ 88 cx_allocator_class *cl; 89 /** 90 * A pointer to the data this allocator uses. 91 */ 92 void *data; 93 }; 94 95 /** 96 * High-Level type alias for the allocator type. 97 */ 98 typedef struct cx_allocator_s CxAllocator; 99 100 /** 101 * A default allocator using standard library malloc() etc. 102 */ 103 cx_attr_export 104 extern const CxAllocator * const cxDefaultAllocator; 105 106 /** 107 * Function pointer type for destructor functions. 108 * 109 * A destructor function deallocates possible contents and MAY free the memory 110 * pointed to by @p memory. Read the documentation of the respective function 111 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in 112 * that particular implementation. 113 * 114 * @param memory a pointer to the object to destruct 115 */ 116 typedef void (*cx_destructor_func)(void *memory); 117 118 /** 119 * Function pointer type for destructor functions. 120 * 121 * A destructor function deallocates possible contents and MAY free the memory 122 * pointed to by @p memory. Read the documentation of the respective function 123 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in 124 * that particular implementation. 125 * 126 * @param data an optional pointer to custom data 127 * @param memory a pointer to the object to destruct 128 */ 129 typedef void (*cx_destructor_func2)( 130 void *data, 131 void *memory 132 ); 133 134 /** 135 * Reallocate a previously allocated block and changes the pointer in-place, 136 * if necessary. 137 * 138 * @par Error handling 139 * @c errno will be set by realloc() on failure. 140 * 141 * @param mem pointer to the pointer to allocated block 142 * @param n the new size in bytes 143 * @retval zero success 144 * @retval non-zero failure 145 * @see cx_reallocatearray() 146 */ 147 cx_attr_nonnull 148 cx_attr_nodiscard 149 cx_attr_export 150 int cx_reallocate_( 151 void **mem, 152 size_t n 153 ); 154 155 /** 156 * Reallocate a previously allocated block and changes the pointer in-place, 157 * if necessary. 158 * 159 * The size is calculated by multiplying @p nemb and @p size. 160 * 161 * @par Error handling 162 * @c errno will be set by realloc() on failure or when the multiplication of 163 * @p nmemb and @p size overflows. 164 * 165 * @param mem pointer to the pointer to allocated block 166 * @param nmemb the number of elements 167 * @param size the size of each element 168 * @retval zero success 169 * @retval non-zero failure 170 * @see cx_reallocate() 171 */ 172 cx_attr_nonnull 173 cx_attr_nodiscard 174 cx_attr_export 175 int cx_reallocatearray_( 176 void **mem, 177 size_t nmemb, 178 size_t size 179 ); 180 181 /** 182 * Reallocate a previously allocated block and changes the pointer in-place, 183 * if necessary. 184 * 185 * @par Error handling 186 * @c errno will be set by realloc() on failure. 187 * 188 * @param mem (@c void**) pointer to the pointer to allocated block 189 * @param n (@c size_t) the new size in bytes 190 * @retval zero success 191 * @retval non-zero failure 192 * @see cx_reallocatearray() 193 */ 194 #define cx_reallocate(mem, n) cx_reallocate_((void**)(mem), n) 195 196 /** 197 * Reallocate a previously allocated block and changes the pointer in-place, 198 * if necessary. 199 * 200 * The size is calculated by multiplying @p nemb and @p size. 201 * 202 * @par Error handling 203 * @c errno will be set by realloc() on failure or when the multiplication of 204 * @p nmemb and @p size overflows. 205 * 206 * @param mem (@c void**) pointer to the pointer to allocated block 207 * @param nmemb (@c size_t) the number of elements 208 * @param size (@c size_t) the size of each element 209 * @retval zero success 210 * @retval non-zero failure 211 */ 212 #define cx_reallocatearray(mem, nmemb, size) \ 213 cx_reallocatearray_((void**)(mem), nmemb, size) 214 215 /** 216 * Free a block allocated by this allocator. 217 * 218 * @note Freeing a block of a different allocator is undefined. 219 * 220 * @param allocator the allocator 221 * @param mem a pointer to the block to free 222 */ 223 cx_attr_nonnull_arg(1) 224 cx_attr_export 225 void cxFree( 226 const CxAllocator *allocator, 227 void *mem 228 ); 229 230 /** 231 * Allocate @p n bytes of memory. 232 * 233 * @param allocator the allocator 234 * @param n the number of bytes 235 * @return a pointer to the allocated memory 236 */ 237 cx_attr_nodiscard 238 cx_attr_nonnull 239 cx_attr_malloc 240 cx_attr_dealloc_ucx 241 cx_attr_allocsize(2) 242 cx_attr_export 243 void *cxMalloc( 244 const CxAllocator *allocator, 245 size_t n 246 ); 247 248 /** 249 * Reallocate the previously allocated block in @p mem, making the new block 250 * @p n bytes long. 251 * This function may return the same pointer that was passed to it, if moving 252 * the memory was not necessary. 253 * 254 * @note Re-allocating a block allocated by a different allocator is undefined. 255 * 256 * @param allocator the allocator 257 * @param mem pointer to the previously allocated block 258 * @param n the new size in bytes 259 * @return a pointer to the reallocated memory 260 */ 261 cx_attr_nodiscard 262 cx_attr_nonnull_arg(1) 263 cx_attr_dealloc_ucx 264 cx_attr_allocsize(3) 265 cx_attr_export 266 void *cxRealloc( 267 const CxAllocator *allocator, 268 void *mem, 269 size_t n 270 ); 271 272 /** 273 * Reallocate the previously allocated block in @p mem, making the new block 274 * @p n bytes long. 275 * This function may return the same pointer that was passed to it, if moving 276 * the memory was not necessary. 277 * 278 * The size is calculated by multiplying @p nemb and @p size. 279 * If that multiplication overflows, this function returns @c NULL and @c errno 280 * will be set. 281 * 282 * @note Re-allocating a block allocated by a different allocator is undefined. 283 * 284 * @param allocator the allocator 285 * @param mem pointer to the previously allocated block 286 * @param nmemb the number of elements 287 * @param size the size of each element 288 * @return a pointer to the reallocated memory 289 */ 290 cx_attr_nodiscard 291 cx_attr_nonnull_arg(1) 292 cx_attr_dealloc_ucx 293 cx_attr_allocsize(3, 4) 294 cx_attr_export 295 void *cxReallocArray( 296 const CxAllocator *allocator, 297 void *mem, 298 size_t nmemb, 299 size_t size 300 ); 301 302 /** 303 * Reallocate a previously allocated block and changes the pointer in-place, 304 * if necessary. 305 * This function acts like cxRealloc() using the pointer pointed to by @p mem. 306 * 307 * @note Re-allocating a block allocated by a different allocator is undefined. 308 * 309 * @par Error handling 310 * @c errno will be set, if the underlying realloc function does so. 311 * 312 * @param allocator the allocator 313 * @param mem pointer to the pointer to allocated block 314 * @param n the new size in bytes 315 * @retval zero success 316 * @retval non-zero failure 317 */ 318 cx_attr_nodiscard 319 cx_attr_nonnull 320 cx_attr_export 321 int cxReallocate_( 322 const CxAllocator *allocator, 323 void **mem, 324 size_t n 325 ); 326 327 /** 328 * Reallocate a previously allocated block and changes the pointer in-place, 329 * if necessary. 330 * This function acts like cxRealloc() using the pointer pointed to by @p mem. 331 * 332 * @note Re-allocating a block allocated by a different allocator is undefined. 333 * 334 * @par Error handling 335 * @c errno will be set, if the underlying realloc function does so. 336 * 337 * @param allocator (@c CxAllocator*) the allocator 338 * @param mem (@c void**) pointer to the pointer to allocated block 339 * @param n (@c size_t) the new size in bytes 340 * @retval zero success 341 * @retval non-zero failure 342 */ 343 #define cxReallocate(allocator, mem, n) \ 344 cxReallocate_(allocator, (void**)(mem), n) 345 346 /** 347 * Reallocate a previously allocated block and changes the pointer in-place, 348 * if necessary. 349 * This function acts like cxReallocArray() using the pointer pointed to 350 * by @p mem. 351 * 352 * @note Re-allocating a block allocated by a different allocator is undefined. 353 * 354 * @par Error handling 355 * @c errno will be set, if the underlying realloc function does so or the 356 * multiplication of @p nmemb and @p size overflows. 357 * 358 * @param allocator the allocator 359 * @param mem pointer to the pointer to allocated block 360 * @param nmemb the number of elements 361 * @param size the size of each element 362 * @retval zero success 363 * @retval non-zero on failure 364 */ 365 cx_attr_nodiscard 366 cx_attr_nonnull 367 cx_attr_export 368 int cxReallocateArray_( 369 const CxAllocator *allocator, 370 void **mem, 371 size_t nmemb, 372 size_t size 373 ); 374 375 /** 376 * Reallocate a previously allocated block and changes the pointer in-place, 377 * if necessary. 378 * This function acts like cxReallocArray() using the pointer pointed to 379 * by @p mem. 380 * 381 * @note Re-allocating a block allocated by a different allocator is undefined. 382 * 383 * @par Error handling 384 * @c errno will be set, if the underlying realloc function does so or the 385 * multiplication of @p nmemb and @p size overflows. 386 * 387 * @param allocator (@c CxAllocator*) the allocator 388 * @param mem (@c void**) pointer to the pointer to allocated block 389 * @param nmemb (@c size_t) the number of elements 390 * @param size (@c size_t) the size of each element 391 * @retval zero success 392 * @retval non-zero failure 393 */ 394 #define cxReallocateArray(allocator, mem, nmemb, size) \ 395 cxReallocateArray_(allocator, (void**) (mem), nmemb, size) 396 397 /** 398 * Allocate @p nmemb elements of @p n bytes each, all initialized to zero. 399 * 400 * @param allocator the allocator 401 * @param nmemb the number of elements 402 * @param size the size of each element in bytes 403 * @return a pointer to the allocated memory 404 */ 405 cx_attr_nonnull_arg(1) 406 cx_attr_nodiscard 407 cx_attr_malloc 408 cx_attr_dealloc_ucx 409 cx_attr_allocsize(2, 3) 410 cx_attr_export 411 void *cxCalloc( 412 const CxAllocator *allocator, 413 size_t nmemb, 414 size_t size 415 ); 416 417 #ifdef __cplusplus 418 } // extern "C" 419 #endif 420 421 #endif // UCX_ALLOCATOR_H 422