1 /* 2 * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * @file 19 * 20 * Context-based Memory Allocator. 21 * 22 * The idea is that each data structure is given a context to allocate from, 23 * and it can create subcontext for that which can be specific allocation 24 * pattern that matches the data structure. 25 * 26 * It is slightly more work to use than palloc (PostgreSQL) or talloc (Samba), 27 * but it avoids the need to have big fully-featured framework that does 28 * everything at once. 29 * 30 * Instead you have small task-specific allocators, and you can always fall 31 * back to raw malloc if you want to valgrind the code. 32 * 33 * Potential variants: 34 * - fully-featured pooled 35 * - randomly failing 36 * - logging 37 * - locking 38 * - guard signatures 39 * - palloc / talloc like API 40 */ 41 42 #ifndef _USUAL_CXALLOC_H_ 43 #define _USUAL_CXALLOC_H_ 44 45 #include <usual/base.h> 46 47 /** 48 * Ops for allocator that takes context. 49 * 50 * NB! - they are not equivalent to cx_* API. The cx_* 51 * functions do additional sanitizing. 52 */ 53 struct CxOps { 54 /** 55 * Allocate memory. 56 * len will not be 0. 57 */ 58 void *(*c_alloc)(void *ctx, size_t len); 59 /** 60 * Resize existing allocation. 61 * Both p and len will not be 0 62 */ 63 void *(*c_realloc)(void *ctx, void *p, size_t len); 64 /** 65 * Free existing allocation. 66 * p will not be 0 67 */ 68 void (*c_free)(void *ctx, void *p); 69 /** 70 * Release all memory in context. 71 * This is not supported by all allocators. 72 */ 73 void (*c_destroy)(void *ctx); 74 }; 75 76 /** 77 * Memory allocation context. 78 */ 79 struct CxMem { 80 const struct CxOps *ops; 81 void *ctx; 82 }; 83 84 /** Shortcut to const CxMem */ 85 typedef const struct CxMem CxMem; 86 87 /* 88 * Basic operations on allocation context. 89 */ 90 91 /** 92 * Allocate memory from context. 93 * 94 * Returns NULL if no memory or len == 0. 95 */ 96 void *cx_alloc(CxMem *cx, size_t len) _MALLOC; 97 98 /** 99 * Change existing allocation. 100 * 101 * If ptr is NULL it creates new allocation. 102 * If len is 0 it frees the memory. 103 */ 104 void *cx_realloc(CxMem *cx, void *ptr, size_t len); 105 106 /** 107 * Free existing allocation. 108 * 109 * Does nothing if ptr is NULL. 110 */ 111 void cx_free(CxMem *cx, void *ptr); 112 113 /** 114 * Release all memory allocated in context. 115 * 116 * Should be called only on contexts that support it. 117 */ 118 void cx_destroy(CxMem *cx); 119 120 /** Allocate and zero-fill memory */ 121 void *cx_alloc0(CxMem *cx, size_t len) _MALLOC; 122 123 /** Allocate and copy */ 124 void *cx_memdup(CxMem *cx, const void *src, size_t len) _MALLOC; 125 126 /** Allocate and copy string */ 127 void *cx_strdup(CxMem *cx, const char *str) _MALLOC; 128 129 /** Print to allocated string, return length or -1 on error. */ 130 int cx_asprintf(CxMem *cx, char **dst_p, const char *fmt, ...) _PRINTF(3, 4); 131 132 /** Print to allocated string, return length or -1 on error */ 133 int cx_vasprintf(CxMem *cx, char **dst_p, const char *fmt, va_list ap) _PRINTF(3, 0); 134 135 /** Print to allocated string, return new string or NULL on error */ 136 char *cx_sprintf(CxMem *cx, const char *fmt, ...) _PRINTF(2, 3); 137 138 /** Print to allocated string, return new string or NULL on error */ 139 char *cx_vsprintf(CxMem *cx, const char *fmt, va_list ap) _PRINTF(2, 0); 140 141 142 /** Allocator that uses libc malloc/realloc/free */ 143 extern CxMem cx_libc_allocator; 144 145 /** Default allocator */ 146 #ifndef USUAL_ALLOC 147 #define USUAL_ALLOC (&cx_libc_allocator) 148 #endif 149 150 #endif 151