Allocator.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifndef Allocator_H
  16. #define Allocator_H
  17. #include <stdlib.h>
  18. #include <stdbool.h>
  19. struct Allocator;
  20. /**
  21. * Writer interface which writes data to memory and
  22. * provides pointers to the memory locations where it wrote.
  23. */
  24. struct Allocator
  25. {
  26. /** The internal state of the Allocator. */
  27. void* const context;
  28. /**
  29. * Free the heap allocations held by the allocator and any of its children.
  30. *
  31. * @param this the Allocator which is being called. Use: allocator->free(allocator);
  32. */
  33. void (* const free)(const struct Allocator* this, const char* identFile, int identLine);
  34. /**
  35. * Add a function to be called when the allocator is freed.
  36. * This helps keep track of memory allocated by third party applications
  37. * which demand to use malloc themselves.
  38. *
  39. * @param callback the function to call.
  40. * @param callbackContext the data to pass the function when calling it.
  41. * @param this the memory allocator.
  42. * @return a pointer which can be passed to notOnFree() to remove the job.
  43. */
  44. void* (* const onFree)(void (*callback)(void* callbackContext),
  45. void* callbackContext,
  46. const struct Allocator* this);
  47. /**
  48. * Remove a function which was registered with onFree().
  49. *
  50. * @param job the return value from calling onFree().
  51. * @param alloc the memory allocator.
  52. * @return true if the job was found and removed, false otherwise.
  53. */
  54. bool (* const notOnFree)(void* job, struct Allocator* alloc);
  55. /**
  56. * Allocate some memory from this memory allocator.
  57. * The allocation will be aligned on the size of a pointer, if you need further alignment then
  58. * you must handle it manually.
  59. *
  60. * @param numberOfBytes how much memory to allocate.
  61. * @param this the memory allocator, use allocator->malloc(10, allocator) to allocate 10 bytes.
  62. * @return a pointer to the newly allocated memory.
  63. * @see malloc()
  64. */
  65. void* (* const malloc)(size_t numberOfBytes,
  66. const struct Allocator* thisAlloc,
  67. const char* identFile,
  68. int identLine);
  69. /**
  70. * Allocate some memory from this memory allocator.
  71. * The allocation will be aligned on the size of a pointer, if you need further alignment then
  72. * you must handle it manually.
  73. * Memory location will be initialized to 0.
  74. *
  75. * @param numberOfBytes how much memory to allocate.
  76. * @param multiplier how many times the number of bytes to allocate.
  77. * @param this the memory allocator.
  78. * @return a pointer to the newly allocated memory.
  79. * @see calloc()
  80. */
  81. void* (* const calloc)(size_t numberOfBytes,
  82. size_t multiplier,
  83. const struct Allocator* thisAlloc,
  84. const char* identFile,
  85. int identLine);
  86. /**
  87. * Allocate some memory and copy something into that memory space.
  88. * The allocation will be aligned on the size of a pointer, if you need further alignment then
  89. * you must handle it manually.
  90. *
  91. * @param numberOfBytes how much memory to allocate.
  92. * @param thisAllocator the memory allocator.
  93. * @param toClone a pointer to something which will be cloned into the newly allocated memory,
  94. * if this is NULL or is not as large as numberOfBytes, undefined behavior will
  95. * result.
  96. * @return a pointer to the newly allocated memory.
  97. */
  98. void* (* const clone)(size_t numberOfBytes,
  99. const struct Allocator* thisAllocator,
  100. const void* toClone,
  101. const char* identFile,
  102. int identLine);
  103. /**
  104. * Re-allocate memory so that an allocation can be expanded.
  105. * The allocation will be aligned on the size of a pointer, if you need further alignment then
  106. * you must handle it manually.
  107. *
  108. * @param originalAllocation a pointer to the original memory allocation which is to be
  109. * reallocated.
  110. * @param numberOfBytes how much memory to allocate.
  111. * @param thisAllocator the memory allocator.
  112. * @return a pointer to the newly allocated memory.
  113. */
  114. void* (* const realloc)(const void* originalAllocation,
  115. size_t numberOfBytes,
  116. const struct Allocator* thisAllocator,
  117. const char* identFile,
  118. int identLine);
  119. /**
  120. * Get a new child of this allocator.
  121. * When this allocator is freed all of its children will be freed as well.
  122. *
  123. * @param this the memory allocator, use Allocator_child(allocator) to get a child.
  124. * @param identFile the name of the file where this was called from to aid in debugging.
  125. * @param identLine the line number where this was called.
  126. * @return a child allocator.
  127. */
  128. struct Allocator* (* const child)(const struct Allocator* thisAlloc,
  129. const char* identFile,
  130. int identLine);
  131. };
  132. #define Allocator_clone(alloc, content) \
  133. alloc->clone(sizeof(*content), alloc, content, __FILE__, __LINE__)
  134. #define Allocator_malloc(alloc, size) \
  135. alloc->malloc(size, alloc, __FILE__, __LINE__);
  136. #define Allocator_calloc(alloc, size, count) \
  137. alloc->calloc(size, count, alloc, __FILE__, __LINE__)
  138. #define Allocator_onFree(alloc, callback, context) \
  139. alloc->onFree(callback, context, alloc)
  140. #define Allocator_notOnFree(alloc, job) \
  141. alloc->notOnFree(job, alloc)
  142. #define Allocator_realloc(alloc, orig, size) \
  143. alloc->realloc(orig, size, alloc, __FILE__, __LINE__)
  144. #define Allocator_child(alloc) \
  145. alloc->child(alloc, __FILE__, __LINE__)
  146. #define Allocator_free(alloc) \
  147. alloc->free(alloc, __FILE__, __LINE__)
  148. #endif /* MEMALLOCATOR_H */