1 /* 2 * ngtcp2 3 * 4 * Copyright (c) 2022 ngtcp2 contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef NGTCP2_OBJALLOC_H 26 #define NGTCP2_OBJALLOC_H 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif /* HAVE_CONFIG_H */ 31 32 #include <ngtcp2/ngtcp2.h> 33 34 #include "ngtcp2_balloc.h" 35 #include "ngtcp2_opl.h" 36 #include "ngtcp2_macro.h" 37 #include "ngtcp2_mem.h" 38 39 /* 40 * ngtcp2_objalloc combines ngtcp2_balloc and ngtcp2_opl, and provides 41 * an object pool with the custom allocator to reduce the allocation 42 * and deallocation overheads for small objects. 43 */ 44 typedef struct ngtcp2_objalloc { 45 ngtcp2_balloc balloc; 46 ngtcp2_opl opl; 47 } ngtcp2_objalloc; 48 49 /* 50 * ngtcp2_objalloc_init initializes |objalloc|. |blklen| is directly 51 * passed to ngtcp2_balloc_init. 52 */ 53 void ngtcp2_objalloc_init(ngtcp2_objalloc *objalloc, size_t blklen, 54 const ngtcp2_mem *mem); 55 56 /* 57 * ngtcp2_objalloc_free releases all allocated resources. 58 */ 59 void ngtcp2_objalloc_free(ngtcp2_objalloc *objalloc); 60 61 /* 62 * ngtcp2_objalloc_clear releases all allocated resources and 63 * initializes its state. 64 */ 65 void ngtcp2_objalloc_clear(ngtcp2_objalloc *objalloc); 66 67 #ifndef NOMEMPOOL 68 # define ngtcp2_objalloc_def(NAME, TYPE, OPLENTFIELD) \ 69 inline static void ngtcp2_objalloc_##NAME##_init( \ 70 ngtcp2_objalloc *objalloc, size_t nmemb, const ngtcp2_mem *mem) { \ 71 ngtcp2_objalloc_init( \ 72 objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \ 73 } \ 74 \ 75 inline static TYPE *ngtcp2_objalloc_##NAME##_get( \ 76 ngtcp2_objalloc *objalloc) { \ 77 ngtcp2_opl_entry *oplent = ngtcp2_opl_pop(&objalloc->opl); \ 78 TYPE *obj; \ 79 int rv; \ 80 \ 81 if (!oplent) { \ 82 rv = \ 83 ngtcp2_balloc_get(&objalloc->balloc, (void **)&obj, sizeof(TYPE)); \ 84 if (rv != 0) { \ 85 return NULL; \ 86 } \ 87 \ 88 return obj; \ 89 } \ 90 \ 91 return ngtcp2_struct_of(oplent, TYPE, OPLENTFIELD); \ 92 } \ 93 \ 94 inline static TYPE *ngtcp2_objalloc_##NAME##_len_get( \ 95 ngtcp2_objalloc *objalloc, size_t len) { \ 96 ngtcp2_opl_entry *oplent = ngtcp2_opl_pop(&objalloc->opl); \ 97 TYPE *obj; \ 98 int rv; \ 99 \ 100 if (!oplent) { \ 101 rv = ngtcp2_balloc_get(&objalloc->balloc, (void **)&obj, len); \ 102 if (rv != 0) { \ 103 return NULL; \ 104 } \ 105 \ 106 return obj; \ 107 } \ 108 \ 109 return ngtcp2_struct_of(oplent, TYPE, OPLENTFIELD); \ 110 } \ 111 \ 112 inline static void ngtcp2_objalloc_##NAME##_release( \ 113 ngtcp2_objalloc *objalloc, TYPE *obj) { \ 114 ngtcp2_opl_push(&objalloc->opl, &obj->OPLENTFIELD); \ 115 } 116 #else /* NOMEMPOOL */ 117 # define ngtcp2_objalloc_def(NAME, TYPE, OPLENTFIELD) \ 118 inline static void ngtcp2_objalloc_##NAME##_init( \ 119 ngtcp2_objalloc *objalloc, size_t nmemb, const ngtcp2_mem *mem) { \ 120 ngtcp2_objalloc_init( \ 121 objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \ 122 } \ 123 \ 124 inline static TYPE *ngtcp2_objalloc_##NAME##_get( \ 125 ngtcp2_objalloc *objalloc) { \ 126 return ngtcp2_mem_malloc(objalloc->balloc.mem, sizeof(TYPE)); \ 127 } \ 128 \ 129 inline static TYPE *ngtcp2_objalloc_##NAME##_len_get( \ 130 ngtcp2_objalloc *objalloc, size_t len) { \ 131 return ngtcp2_mem_malloc(objalloc->balloc.mem, len); \ 132 } \ 133 \ 134 inline static void ngtcp2_objalloc_##NAME##_release( \ 135 ngtcp2_objalloc *objalloc, TYPE *obj) { \ 136 ngtcp2_mem_free(objalloc->balloc.mem, obj); \ 137 } 138 #endif /* NOMEMPOOL */ 139 140 #endif /* NGTCP2_OBJALLOC_H */ 141