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 __attribute__((__warn_unused_result__)); 63 64 /** 65 * The allocator's calloc() implementation. 66 */ 67 void *(*calloc)( 68 void *data, 69 size_t nelem, 70 size_t n 71 ); 72 73 /** 74 * The allocator's free() implementation. 75 */ 76 void (*free)( 77 void *data, 78 void *mem 79 ) 80 __attribute__((__nonnull__)); 81 } cx_allocator_class; 82 83 /** 84 * Structure holding the data for an allocator. 85 */ 86 struct cx_allocator_s { 87 /** 88 * A pointer to the instance of the allocator class. 89 */ 90 cx_allocator_class *cl; 91 /** 92 * A pointer to the data this allocator uses. 93 */ 94 void *data; 95 }; 96 97 /** 98 * High-Level type alias for the allocator type. 99 */ 100 typedef struct cx_allocator_s CxAllocator; 101 102 /** 103 * A default allocator using standard library malloc() etc. 104 */ 105 extern CxAllocator *cxDefaultAllocator; 106 107 /** 108 * Function pointer type for destructor functions. 109 * 110 * A destructor function deallocates possible contents and MAY free the memory 111 * pointed to by \p memory. Read the documentation of the respective function 112 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in that 113 * particular implementation. 114 * 115 * @param memory a pointer to the object to destruct 116 */ 117 typedef void (*cx_destructor_func)(void *memory) __attribute__((__nonnull__)); 118 119 /** 120 * Function pointer type for destructor functions. 121 * 122 * A destructor function deallocates possible contents and MAY free the memory 123 * pointed to by \p memory. Read the documentation of the respective function 124 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in that 125 * particular implementation. 126 * 127 * @param data an optional pointer to custom data 128 * @param memory a pointer to the object to destruct 129 */ 130 typedef void (*cx_destructor_func2)( 131 void *data, 132 void *memory 133 ) __attribute__((__nonnull__(2))); 134 135 /** 136 * Re-allocate a previously allocated block and changes the pointer in-place, 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 * @return zero on success, non-zero on failure 144 */ 145 int cx_reallocate( 146 void **mem, 147 size_t n 148 ) 149 __attribute__((__nonnull__)); 150 151 /** 152 * Allocate \p n bytes of memory. 153 * 154 * @param allocator the allocator 155 * @param n the number of bytes 156 * @return a pointer to the allocated memory 157 */ 158 void *cxMalloc( 159 CxAllocator const *allocator, 160 size_t n 161 ) 162 __attribute__((__malloc__)) 163 __attribute__((__alloc_size__(2))); 164 165 /** 166 * Re-allocate the previously allocated block in \p mem, making the new block \p n bytes long. 167 * This function may return the same pointer that was passed to it, if moving the memory 168 * was not necessary. 169 * 170 * \note Re-allocating a block allocated by a different allocator is undefined. 171 * 172 * @param allocator the allocator 173 * @param mem pointer to the previously allocated block 174 * @param n the new size in bytes 175 * @return a pointer to the re-allocated memory 176 */ 177 void *cxRealloc( 178 CxAllocator const *allocator, 179 void *mem, 180 size_t n 181 ) 182 __attribute__((__warn_unused_result__)) 183 __attribute__((__alloc_size__(3))); 184 185 /** 186 * Re-allocate a previously allocated block and changes the pointer in-place, if necessary. 187 * This function acts like cxRealloc() using the pointer pointed to by \p mem. 188 * 189 * \note Re-allocating a block allocated by a different allocator is undefined. 190 * 191 * \par Error handling 192 * \c errno will be set, if the underlying realloc function does so. 193 * 194 * @param allocator the allocator 195 * @param mem pointer to the pointer to allocated block 196 * @param n the new size in bytes 197 * @return zero on success, non-zero on failure 198 */ 199 int cxReallocate( 200 CxAllocator const *allocator, 201 void **mem, 202 size_t n 203 ) 204 __attribute__((__nonnull__)); 205 206 /** 207 * Allocate \p nelem elements of \p n bytes each, all initialized to zero. 208 * 209 * @param allocator the allocator 210 * @param nelem the number of elements 211 * @param n the size of each element in bytes 212 * @return a pointer to the allocated memory 213 */ 214 void *cxCalloc( 215 CxAllocator const *allocator, 216 size_t nelem, 217 size_t n 218 ) 219 __attribute__((__malloc__)) 220 __attribute__((__alloc_size__(2, 3))); 221 222 /** 223 * Free a block allocated by this allocator. 224 * 225 * \note Freeing a block of a different allocator is undefined. 226 * 227 * @param allocator the allocator 228 * @param mem a pointer to the block to free 229 */ 230 void cxFree( 231 CxAllocator const *allocator, 232 void *mem 233 ) 234 __attribute__((__nonnull__)); 235 236 #ifdef __cplusplus 237 } // extern "C" 238 #endif 239 240 #endif // UCX_ALLOCATOR_H 241