A collection of basic/generally desirable code I use across multiple C++ projects.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
4.8 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "alloc.h"
  2. #include "string.h"
  3. #include "print.h"
  4. #include "types.h"
  5. #if false
  6. static void* leakcheckMalloc(size_t size, const char* file, s32 line) {
  7. ULE_TYPES_H_FTAG;
  8. return malloc(size);
  9. }
  10. static void* leakcheckCalloc(size_t maxNumOfElements, size_t elementSize, const char* file, s32 line) {
  11. ULE_TYPES_H_FTAG;
  12. return calloc(maxNumOfElements, elementSize);
  13. }
  14. static void* leakcheckRealloc(void* buffer, size_t newSize, const char* file, s32 line) {
  15. ULE_TYPES_H_FTAG;
  16. return realloc(buffer, newSize);
  17. }
  18. static void leakcheckFree(void* ptr, const char* file, s32 line) {
  19. ULE_TYPES_H_FTAG;
  20. free(ptr);
  21. }
  22. #define malloc(size) leakcheckMalloc(size, __FILE__, __LINE__)
  23. #define calloc(numElements, size) leakcheckCalloc(numElements, size, __FILE__, __LINE__)
  24. #define realloc(buffer, newSize) leakcheckRealloc(buffer, newSize, __FILE__, __LINE__)
  25. #define free(ptr) leakcheckFree(ptr, __FILE__, __LINE__)
  26. static void dumpLeaks() {
  27. void* address;
  28. size_t size;
  29. const char* file;
  30. s32 line;
  31. for (;;) {
  32. println("%p - %lu, %s:%d", address, size, file, line);
  33. }
  34. }
  35. #endif
  36. // system allocators
  37. void* pMalloc(size_t size) {
  38. ULE_TYPES_H_FTAG;
  39. void* p = malloc(size);
  40. if (!p) {
  41. die("Out of memory!n\nfailed to malloc %p with size %u\n", p, size);
  42. }
  43. return p;
  44. }
  45. void* pMalloc(size_t size, void* allocatorState) {
  46. ULE_TYPES_H_FTAG;
  47. return pMalloc(size);
  48. }
  49. void* pCalloc(size_t maxNumOfElements, size_t elementSize) {
  50. ULE_TYPES_H_FTAG;
  51. void* p = calloc(maxNumOfElements, elementSize);
  52. if (!p) {
  53. die("Out of memory!\nfailed to calloc %p with %u elements of size %u\n", p, maxNumOfElements, elementSize);
  54. }
  55. return p;
  56. }
  57. void* pCalloc(size_t maxNumOfElements, size_t elementSize, void* allocatorState) {
  58. ULE_TYPES_H_FTAG;
  59. return pCalloc(maxNumOfElements, elementSize);
  60. }
  61. void* pRealloc(void* buffer, size_t newSize) {
  62. ULE_TYPES_H_FTAG;
  63. void* p = realloc(buffer, newSize);
  64. if (!p) {
  65. //pFree(buffer); // if we ever *don't* terminate the program at this point, we should free |buffer|
  66. die("Out of memory!\nfailed to realloc %p with size: %u\n", buffer, newSize);
  67. }
  68. return p;
  69. }
  70. void* pRealloc(void* buffer, size_t newSize, void* allocatorState) {
  71. ULE_TYPES_H_FTAG;
  72. return pRealloc(buffer, newSize);
  73. }
  74. void pFree(void* ptr) {
  75. ULE_TYPES_H_FTAG;
  76. free(ptr);
  77. }
  78. void pFree(void* ptr, void* allocatorState) {
  79. ULE_TYPES_H_FTAG;
  80. pFree(ptr);
  81. }
  82. void pFree(const void* ptr) {
  83. ULE_TYPES_H_FTAG;
  84. pFree((void*) ptr);
  85. }
  86. void pFree(const void* ptr, void* allocatorState) {
  87. ULE_TYPES_H_FTAG;
  88. pFree((void*) ptr, allocatorState);
  89. }
  90. #ifdef malloc
  91. #undef malloc
  92. #endif
  93. #ifdef calloc
  94. #undef calloc
  95. #endif
  96. #ifdef realloc
  97. #undef realloc
  98. #endif
  99. #ifdef free
  100. #undef free
  101. #endif
  102. static bool DefaultAllocatorInited = false;
  103. static Allocator DefaultAllocator;
  104. static void defaultAllocatorInit() {
  105. ULE_TYPES_H_FTAG;
  106. DefaultAllocator.state = null;
  107. DefaultAllocator.mallocate = pMalloc;
  108. DefaultAllocator.callocate = pCalloc;
  109. DefaultAllocator.reallocate = pRealloc;
  110. DefaultAllocator.free = pFree;
  111. DefaultAllocatorInited = true;
  112. }
  113. Allocator* Allocator::GetDefault() {
  114. ULE_TYPES_H_FTAG;
  115. if (!DefaultAllocatorInited) defaultAllocatorInit();
  116. return &DefaultAllocator;
  117. }
  118. //================================================================================
  119. // alignment should be a power of 2
  120. static u64 alignForward2(u64 ptr, size_t alignment) {
  121. ULE_TYPES_H_FTAG;
  122. u64 p, a, modulo;
  123. p = ptr;
  124. a = alignment;
  125. modulo = p & (a - 1);
  126. if (modulo != 0) {
  127. p += a - modulo;
  128. }
  129. return p;
  130. }
  131. static u64 alignForward(u64 ptr, size_t alignment) {
  132. ULE_TYPES_H_FTAG;
  133. return ((ptr + alignment - 1) / alignment) * alignment;
  134. }
  135. //================================================================================
  136. // Scratch/Arena
  137. Arena* Arena::Init(u32 sizeInBytes) {
  138. ULE_TYPES_H_FTAG;
  139. Arena* arena = (Arena*) pMalloc(sizeof(Arena));
  140. arena->index = 0;
  141. arena->buffer = (u8*) pMalloc(sizeof(u8) * sizeInBytes);
  142. arena->bufferSizeInBytes = sizeInBytes;
  143. return arena;
  144. }
  145. void* Arena::Alloc(u32 sizeInBytes) {
  146. ULE_TYPES_H_FTAG;
  147. u8* p = this->buffer + this->index;
  148. u32 offset = (u32) alignForward2((u64) p, 64);
  149. if ((void*)(offset + sizeInBytes) <= (this->buffer + this->bufferSizeInBytes)) {
  150. void* ptr = &this->buffer[offset];
  151. this->index += offset + sizeInBytes;
  152. String::memset(ptr, 0, sizeInBytes);
  153. return ptr;
  154. }
  155. return null;
  156. }
  157. void Arena::Clear() {
  158. ULE_TYPES_H_FTAG;
  159. this->index = 0;
  160. }
  161. //================================================================================
  162. struct StackAllocator {
  163. u32 bufferSize;
  164. u32 index;
  165. u8* buffer;
  166. };
  167. struct PoolAllocator {
  168. u8* buffer;
  169. };