ngtcp2_objalloc.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. #ifdef HAVE_CONFIG_H
  28. # include <config.h>
  29. #endif /* defined(HAVE_CONFIG_H) */
  30. #include <ngtcp2/ngtcp2.h>
  31. #include "ngtcp2_balloc.h"
  32. #include "ngtcp2_opl.h"
  33. #include "ngtcp2_macro.h"
  34. #include "ngtcp2_mem.h"
  35. /*
  36. * ngtcp2_objalloc combines ngtcp2_balloc and ngtcp2_opl, and provides
  37. * an object pool with the custom allocator to reduce the allocation
  38. * and deallocation overheads for small objects.
  39. */
  40. typedef struct ngtcp2_objalloc {
  41. ngtcp2_balloc balloc;
  42. ngtcp2_opl opl;
  43. } ngtcp2_objalloc;
  44. /*
  45. * ngtcp2_objalloc_init initializes |objalloc|. |blklen| is directly
  46. * passed to ngtcp2_balloc_init.
  47. */
  48. void ngtcp2_objalloc_init(ngtcp2_objalloc *objalloc, size_t blklen,
  49. const ngtcp2_mem *mem);
  50. /*
  51. * ngtcp2_objalloc_free releases all allocated resources.
  52. */
  53. void ngtcp2_objalloc_free(ngtcp2_objalloc *objalloc);
  54. /*
  55. * ngtcp2_objalloc_clear releases all allocated resources and
  56. * initializes its state.
  57. */
  58. void ngtcp2_objalloc_clear(ngtcp2_objalloc *objalloc);
  59. #ifndef NOMEMPOOL
  60. # define ngtcp2_objalloc_decl(NAME, TYPE, OPLENTFIELD) \
  61. inline static void ngtcp2_objalloc_##NAME##_init( \
  62. ngtcp2_objalloc *objalloc, size_t nmemb, const ngtcp2_mem *mem) { \
  63. ngtcp2_objalloc_init( \
  64. objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \
  65. } \
  66. \
  67. TYPE *ngtcp2_objalloc_##NAME##_get(ngtcp2_objalloc *objalloc); \
  68. \
  69. TYPE *ngtcp2_objalloc_##NAME##_len_get(ngtcp2_objalloc *objalloc, \
  70. size_t len); \
  71. \
  72. inline static void ngtcp2_objalloc_##NAME##_release( \
  73. ngtcp2_objalloc *objalloc, TYPE *obj) { \
  74. ngtcp2_opl_push(&objalloc->opl, &obj->OPLENTFIELD); \
  75. }
  76. # define ngtcp2_objalloc_def(NAME, TYPE, OPLENTFIELD) \
  77. TYPE *ngtcp2_objalloc_##NAME##_get(ngtcp2_objalloc *objalloc) { \
  78. ngtcp2_opl_entry *oplent = ngtcp2_opl_pop(&objalloc->opl); \
  79. TYPE *obj; \
  80. int rv; \
  81. \
  82. if (!oplent) { \
  83. rv = \
  84. ngtcp2_balloc_get(&objalloc->balloc, (void **)&obj, sizeof(TYPE)); \
  85. if (rv != 0) { \
  86. return NULL; \
  87. } \
  88. \
  89. return obj; \
  90. } \
  91. \
  92. return ngtcp2_struct_of(oplent, TYPE, OPLENTFIELD); \
  93. } \
  94. \
  95. TYPE *ngtcp2_objalloc_##NAME##_len_get(ngtcp2_objalloc *objalloc, \
  96. size_t len) { \
  97. ngtcp2_opl_entry *oplent = ngtcp2_opl_pop(&objalloc->opl); \
  98. TYPE *obj; \
  99. int rv; \
  100. \
  101. if (!oplent) { \
  102. rv = ngtcp2_balloc_get(&objalloc->balloc, (void **)&obj, len); \
  103. if (rv != 0) { \
  104. return NULL; \
  105. } \
  106. \
  107. return obj; \
  108. } \
  109. \
  110. return ngtcp2_struct_of(oplent, TYPE, OPLENTFIELD); \
  111. }
  112. #else /* defined(NOMEMPOOL) */
  113. # define ngtcp2_objalloc_decl(NAME, TYPE, OPLENTFIELD) \
  114. inline static void ngtcp2_objalloc_##NAME##_init( \
  115. ngtcp2_objalloc *objalloc, size_t nmemb, const ngtcp2_mem *mem) { \
  116. ngtcp2_objalloc_init( \
  117. objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \
  118. } \
  119. \
  120. inline static TYPE *ngtcp2_objalloc_##NAME##_get( \
  121. ngtcp2_objalloc *objalloc) { \
  122. return ngtcp2_mem_malloc(objalloc->balloc.mem, sizeof(TYPE)); \
  123. } \
  124. \
  125. inline static TYPE *ngtcp2_objalloc_##NAME##_len_get( \
  126. ngtcp2_objalloc *objalloc, size_t len) { \
  127. return ngtcp2_mem_malloc(objalloc->balloc.mem, len); \
  128. } \
  129. \
  130. inline static void ngtcp2_objalloc_##NAME##_release( \
  131. ngtcp2_objalloc *objalloc, TYPE *obj) { \
  132. ngtcp2_mem_free(objalloc->balloc.mem, obj); \
  133. }
  134. # define ngtcp2_objalloc_def(NAME, TYPE, OPLENTFIELD)
  135. #endif /* defined(NOMEMPOOL) */
  136. #endif /* !defined(NGTCP2_OBJALLOC_H) */