| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | 
							- #include "core/Utility.h"
 
- #include <stdio.h>
 
- #include <stdlib.h>
 
- #include <string.h>
 
- #include <threads.h>
 
- #include <time.h>
 
- #include "ErrorSimulator.h"
 
- #include "core/Logger.h"
 
- extern inline size_t coreMaxSize(size_t a, size_t b);
 
- extern inline size_t coreMinSize(size_t a, size_t b);
 
- static CoreExitHandler exitHandler = nullptr;
 
- static void* exitData = nullptr;
 
- static CoreOutOfMemoryHandler outOfMemoryHandler = nullptr;
 
- static void* outOfMemoryData = nullptr;
 
- size_t corePopCount(u64 u) {
 
-     static const u64 map[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
 
-     size_t sum = 0;
 
-     for(size_t i = 0; i < sizeof(u64) * 8; i += 4) {
 
-         sum += map[(u >> i) & 0xF];
 
-     }
 
-     return sum;
 
- }
 
- size_t coreToStringSize(const void* p, char* buffer, size_t n) {
 
-     int w = snprintf(buffer, n, "%zu", *(const size_t*)p);
 
-     return w < 0 ? 0 : (size_t)w;
 
- }
 
- size_t coreToStringInt(const void* p, char* buffer, size_t n) {
 
-     int w = snprintf(buffer, n, "%d", *(const int*)p);
 
-     return w < 0 ? 0 : (size_t)w;
 
- }
 
- void coreStringAdd(size_t* w, char** buffer, size_t* n, size_t shift) {
 
-     *w += shift;
 
-     if(*n > shift) {
 
-         *buffer += shift;
 
-         *n -= shift;
 
-     } else {
 
-         *n = 0;
 
-     }
 
- }
 
- void coreStringAddI(size_t* w, char** buffer, size_t* n, int shift) {
 
-     coreStringAdd(w, buffer, n, shift < 0 ? 0 : (size_t)shift);
 
- }
 
- [[noreturn]] void coreExitWithHandler(const char* file, int line, int value) {
 
-     if(value != 0) {
 
-         file = coreGetShortFileName(file);
 
-         CORE_LOG_ERROR("Exit from %s:%d with value %d", file, line, value);
 
-     }
 
-     if(exitHandler != nullptr) {
 
-         exitHandler(value, exitData);
 
-     }
 
-     exit(value);
 
- }
 
- void coreSetExitHandler(CoreExitHandler eh, void* data) {
 
-     exitHandler = eh;
 
-     exitData = data;
 
- }
 
- void coreSetOutOfMemoryHandler(CoreOutOfMemoryHandler h, void* data) {
 
-     outOfMemoryHandler = h;
 
-     outOfMemoryData = data;
 
- }
 
- static void* exitOnNull(void* p, size_t n) {
 
-     if(p == nullptr) {
 
-         CORE_LOG_ERROR("Out of memory, requested '%zu' bytes", n);
 
-         CORE_EXIT(1);
 
-     }
 
-     return p;
 
- }
 
- static void* coreRealAllocate(size_t n) {
 
-     void* p = malloc(n);
 
-     while(p == nullptr && outOfMemoryHandler != nullptr) {
 
-         outOfMemoryHandler(outOfMemoryData);
 
-         p = malloc(n);
 
-     }
 
-     return exitOnNull(p, n);
 
- }
 
- static void* coreRealReallocate(void* oldP, size_t n) {
 
-     if(n <= 0) {
 
-         free(oldP);
 
-         return nullptr;
 
-     }
 
-     void* p = realloc(oldP, n);
 
-     if(p == nullptr) {
 
-         while(p == nullptr && outOfMemoryHandler != nullptr) {
 
-             outOfMemoryHandler(outOfMemoryData);
 
-             p = realloc(oldP, n);
 
-         }
 
-     }
 
-     return exitOnNull(p, n);
 
- }
 
- static void coreRealFree(void* p) {
 
-     free(p);
 
- }
 
- #ifdef CORE_CHECK_MEMORY
 
- static const u8 CANARY[16] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
 
-                               0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF};
 
- struct CoreMemoryInfo;
 
- typedef struct CoreMemoryInfo CoreMemoryInfo;
 
- struct CoreMemoryInfo {
 
-     CoreMemoryInfo* next;
 
-     CoreMemoryInfo* previous;
 
-     size_t size;
 
-     int line;
 
-     char buffer[64 - 2 * sizeof(void*) - sizeof(size_t) - sizeof(int)];
 
-     char canary[sizeof(CANARY)];
 
- };
 
- static_assert(sizeof(CoreMemoryInfo) == 80, "memory info has invalid size");
 
- static CoreMemoryInfo* headMemoryInfo = nullptr;
 
- static void addMemoryInfo(CoreMemoryInfo* info, const char* file, int line,
 
-                           size_t n) {
 
-     info->next = nullptr;
 
-     info->previous = nullptr;
 
-     info->size = n;
 
-     info->line = line;
 
-     strncpy(info->buffer, coreGetShortFileName(file), sizeof(info->buffer));
 
-     memcpy(info->canary, CANARY, sizeof(CANARY));
 
-     memcpy((char*)info + n - sizeof(CANARY), CANARY, sizeof(CANARY));
 
-     if(headMemoryInfo == nullptr) {
 
-         headMemoryInfo = info;
 
-     } else {
 
-         headMemoryInfo->previous = info;
 
-         info->next = headMemoryInfo;
 
-         headMemoryInfo = info;
 
-     }
 
- }
 
- static void removeMemoryInfo(CoreMemoryInfo* info) {
 
-     if(info->previous == nullptr) {
 
-         if(info->next == nullptr) {
 
-             headMemoryInfo = nullptr;
 
-         } else {
 
-             headMemoryInfo = info->next;
 
-             info->next->previous = nullptr;
 
-         }
 
-     } else {
 
-         if(info->next == nullptr) {
 
-             info->previous->next = nullptr;
 
-         } else {
 
-             info->previous->next = info->next;
 
-             info->next->previous = info->previous;
 
-         }
 
-     }
 
- }
 
- void* coreDebugAllocate(const char* file, int line, size_t n) {
 
-     n += sizeof(CoreMemoryInfo) + sizeof(CANARY);
 
-     void* p = coreRealAllocate(n + sizeof(CANARY));
 
-     addMemoryInfo(p, file, line, n);
 
-     return (char*)p + sizeof(CoreMemoryInfo);
 
- }
 
- void* coreDebugReallocate(const char* file, int line, void* p, size_t n) {
 
-     if(n > 0) {
 
-         n += sizeof(CoreMemoryInfo) + sizeof(CANARY);
 
-     }
 
-     void* rp = (void*)p;
 
-     if(rp != nullptr) {
 
-         rp = (char*)rp - sizeof(CoreMemoryInfo);
 
-         removeMemoryInfo(rp);
 
-     }
 
-     void* np = coreRealReallocate(rp, n);
 
-     if(np == nullptr) {
 
-         return nullptr;
 
-     }
 
-     addMemoryInfo(np, file, line, n);
 
-     return (char*)np + sizeof(CoreMemoryInfo);
 
- }
 
- static bool checkCanary(void* p) {
 
-     return memcmp(p, CANARY, sizeof(CANARY)) != 0;
 
- }
 
- void coreFreeDebug(const char* file, int line, void* p) {
 
-     if(p == nullptr) {
 
-         return;
 
-     }
 
-     CoreMemoryInfo* rp = nullptr;
 
-     void* w = (char*)p - sizeof(CoreMemoryInfo);
 
-     memcpy(&rp, &w, sizeof(rp));
 
-     // CoreMemoryInfo* rp = (CoreMemoryInfo*)((char*)p -
 
-     // sizeof(CoreMemoryInfo));
 
-     if(checkCanary(rp->canary)) {
 
-         file = coreGetShortFileName(file);
 
-         CORE_LOG_ERROR("Free at %s:%d violated pre canary", file, line);
 
-         CORE_EXIT(1);
 
-     } else if(checkCanary((char*)rp + rp->size - sizeof(CANARY))) {
 
-         file = coreGetShortFileName(file);
 
-         CORE_LOG_ERROR("Free at %s:%d violated post canary", file, line);
 
-         CORE_EXIT(1);
 
-     }
 
-     removeMemoryInfo(rp);
 
-     coreRealFree(rp);
 
- }
 
- void corePrintMemoryReport() {
 
-     for(CoreMemoryInfo* i = headMemoryInfo; i != nullptr; i = i->next) {
 
-         CORE_LOG_ERROR("%s:%d was not freed", i->buffer, i->line);
 
-     }
 
- }
 
- #else
 
- void* coreAllocate(size_t n) {
 
-     return coreRealAllocate(n);
 
- }
 
- void* coreReallocate(void* p, size_t n) {
 
-     return coreRealReallocate(p, n);
 
- }
 
- void coreFree(void* p) {
 
-     coreRealFree(p);
 
- }
 
- #endif
 
- bool coreSleep(i64 nanos) {
 
-     struct timespec t;
 
-     t.tv_nsec = nanos % 1'000'000'000;
 
-     t.tv_sec = nanos / 1'000'000'000;
 
-     return thrd_sleep(&t, nullptr) != 0;
 
- }
 
- i64 coreNanos(void) {
 
-     struct timespec ts;
 
-     if(timespec_get(&ts, TIME_UTC) == 0 || CORE_TIME_GET_FAIL) {
 
-         return -1;
 
-     }
 
-     return (i64)ts.tv_sec * 1'000'000'000L + (i64)ts.tv_nsec;
 
- }
 
 
  |