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