|
@@ -1,22 +1,14 @@
|
|
|
-#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"
|
|
|
-
|
|
|
-#define MIN_MAX_DEF(type, name) \
|
|
|
- extern inline type max##name(type a, type b); \
|
|
|
- extern inline type min##name(type a, type b); \
|
|
|
- extern inline type clamp##name(type t, type from, type to)
|
|
|
-MIN_MAX_DEF(size_t, Size);
|
|
|
-MIN_MAX_DEF(u32, U32);
|
|
|
-MIN_MAX_DEF(i32, I32);
|
|
|
-MIN_MAX_DEF(float, Float);
|
|
|
+#include "core/Utility.hpp"
|
|
|
+
|
|
|
+#include <chrono>
|
|
|
+#include <cstdio>
|
|
|
+#include <cstdlib>
|
|
|
+#include <cstring>
|
|
|
+#include <ctime>
|
|
|
+#include <thread>
|
|
|
+
|
|
|
+#include "ErrorSimulator.hpp"
|
|
|
+#include "core/Logger.hpp"
|
|
|
|
|
|
static ExitHandler exitHandler = nullptr;
|
|
|
static void* exitData = nullptr;
|
|
@@ -35,7 +27,7 @@ size_t popCount(u64 u) {
|
|
|
[[noreturn]] void exitWithHandler(const char* file, int line, int value) {
|
|
|
if(value != 0) {
|
|
|
file = getShortFileName(file);
|
|
|
- LOG_ERROR("Exit from %s:%d with value %d", file, line, value);
|
|
|
+ LOG_ERROR("Exit from #:# with value #", file, line, value);
|
|
|
}
|
|
|
if(exitHandler != nullptr) {
|
|
|
exitHandler(value, exitData);
|
|
@@ -55,7 +47,7 @@ void setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) {
|
|
|
|
|
|
static void* exitOnNull(void* p, size_t n) {
|
|
|
if(p == nullptr) {
|
|
|
- LOG_ERROR("Out of memory, requested '%zu' bytes", n);
|
|
|
+ LOG_ERROR("Out of memory, requested '#' bytes", n);
|
|
|
EXIT(1);
|
|
|
}
|
|
|
return p;
|
|
@@ -93,9 +85,6 @@ static void RealFree(void* p) {
|
|
|
static const u8 CANARY[16] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
|
|
|
0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF};
|
|
|
|
|
|
-struct MemoryInfo;
|
|
|
-typedef struct MemoryInfo MemoryInfo;
|
|
|
-
|
|
|
struct MemoryInfo {
|
|
|
MemoryInfo* next;
|
|
|
MemoryInfo* previous;
|
|
@@ -116,7 +105,9 @@ static void addMemoryInfo(
|
|
|
info->line = line;
|
|
|
snprintf(info->buffer, sizeof(info->buffer), "%s", getShortFileName(file));
|
|
|
memcpy(info->canary, CANARY, sizeof(CANARY));
|
|
|
- memcpy((char*)info + n - sizeof(CANARY), CANARY, sizeof(CANARY));
|
|
|
+ memcpy(
|
|
|
+ reinterpret_cast<char*>(info) + n - sizeof(CANARY), CANARY,
|
|
|
+ sizeof(CANARY));
|
|
|
if(headMemoryInfo == nullptr) {
|
|
|
headMemoryInfo = info;
|
|
|
} else {
|
|
@@ -147,8 +138,8 @@ static void removeMemoryInfo(MemoryInfo* info) {
|
|
|
void* coreDebugAllocate(const char* file, int line, size_t n) {
|
|
|
n += sizeof(MemoryInfo) + sizeof(CANARY);
|
|
|
void* p = RealAllocate(n + sizeof(CANARY));
|
|
|
- addMemoryInfo(p, file, line, n);
|
|
|
- return (char*)p + sizeof(MemoryInfo);
|
|
|
+ addMemoryInfo(static_cast<MemoryInfo*>(p), file, line, n);
|
|
|
+ return static_cast<char*>(p) + sizeof(MemoryInfo);
|
|
|
}
|
|
|
|
|
|
void* coreDebugZeroAllocate(const char* file, int line, size_t n) {
|
|
@@ -161,36 +152,36 @@ void* coreDebugReallocate(const char* file, int line, void* p, size_t n) {
|
|
|
if(n > 0) {
|
|
|
n += sizeof(MemoryInfo) + sizeof(CANARY);
|
|
|
}
|
|
|
- void* rp = (void*)p;
|
|
|
+ void* rp = p;
|
|
|
if(rp != nullptr) {
|
|
|
- rp = (char*)rp - sizeof(MemoryInfo);
|
|
|
- removeMemoryInfo(rp);
|
|
|
+ rp = static_cast<char*>(rp) - sizeof(MemoryInfo);
|
|
|
+ removeMemoryInfo(static_cast<MemoryInfo*>(rp));
|
|
|
}
|
|
|
void* np = RealReallocate(rp, n);
|
|
|
if(np == nullptr) {
|
|
|
return nullptr;
|
|
|
}
|
|
|
- addMemoryInfo(np, file, line, n);
|
|
|
- return (char*)np + sizeof(MemoryInfo);
|
|
|
+ addMemoryInfo(static_cast<MemoryInfo*>(np), file, line, n);
|
|
|
+ return static_cast<char*>(np) + sizeof(MemoryInfo);
|
|
|
}
|
|
|
|
|
|
static bool checkCanary(void* p) {
|
|
|
return memcmp(p, CANARY, sizeof(CANARY)) != 0;
|
|
|
}
|
|
|
|
|
|
-void coreFreeDebug(const char* file, int line, void* p) {
|
|
|
+void coreFreeDebug(void* p) {
|
|
|
if(p == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
- void* w = (char*)p - sizeof(MemoryInfo);
|
|
|
- MemoryInfo* rp = w;
|
|
|
+ void* w = static_cast<char*>(p) - sizeof(MemoryInfo);
|
|
|
+ MemoryInfo* rp = static_cast<MemoryInfo*>(w);
|
|
|
+ rp->buffer[sizeof(rp->buffer) - 1] = '\0';
|
|
|
if(checkCanary(rp->canary)) {
|
|
|
- file = getShortFileName(file);
|
|
|
- LOG_ERROR("Free at %s:%d violated pre canary", file, line);
|
|
|
+ LOG_ERROR("Free at #:# violated pre canary", rp->buffer, rp->line);
|
|
|
EXIT(1);
|
|
|
- } else if(checkCanary((char*)rp + rp->size - sizeof(CANARY))) {
|
|
|
- file = getShortFileName(file);
|
|
|
- LOG_ERROR("Free at %s:%d violated post canary", file, line);
|
|
|
+ } else if(checkCanary(
|
|
|
+ reinterpret_cast<char*>(rp) + rp->size - sizeof(CANARY))) {
|
|
|
+ LOG_ERROR("Free at #:# violated post canary", rp->buffer, rp->line);
|
|
|
EXIT(1);
|
|
|
}
|
|
|
removeMemoryInfo(rp);
|
|
@@ -199,10 +190,42 @@ void coreFreeDebug(const char* file, int line, void* p) {
|
|
|
|
|
|
void printMemoryReport() {
|
|
|
for(MemoryInfo* i = headMemoryInfo; i != nullptr; i = i->next) {
|
|
|
- LOG_ERROR("%s:%d was not freed", i->buffer, i->line);
|
|
|
+ LOG_ERROR("#:# was not freed", i->buffer, i->line);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void* operator new(size_t count) {
|
|
|
+ return coreDebugAllocate("unknown", -1, count);
|
|
|
+}
|
|
|
+
|
|
|
+void* operator new(size_t count, const char* file, int line) {
|
|
|
+ return coreDebugAllocate(file, line, count);
|
|
|
+}
|
|
|
+
|
|
|
+void* operator new[](size_t count) {
|
|
|
+ return coreDebugAllocate("unknown", -1, count);
|
|
|
+}
|
|
|
+
|
|
|
+void* operator new[](size_t count, const char* file, int line) {
|
|
|
+ return coreDebugAllocate(file, line, count);
|
|
|
+}
|
|
|
+
|
|
|
+void operator delete(void* p) noexcept {
|
|
|
+ coreFreeDebug(p);
|
|
|
+}
|
|
|
+
|
|
|
+void operator delete(void* p, size_t) noexcept {
|
|
|
+ coreFreeDebug(p);
|
|
|
+}
|
|
|
+
|
|
|
+void operator delete[](void* p) noexcept {
|
|
|
+ coreFreeDebug(p);
|
|
|
+}
|
|
|
+
|
|
|
+void operator delete[](void* p, size_t) noexcept {
|
|
|
+ coreFreeDebug(p);
|
|
|
+}
|
|
|
+
|
|
|
#else
|
|
|
|
|
|
void* coreAllocate(size_t n) {
|
|
@@ -226,10 +249,13 @@ void coreFree(void* p) {
|
|
|
#endif
|
|
|
|
|
|
bool sleepNanos(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;
|
|
|
+ try {
|
|
|
+ FAIL_STEP_THROW();
|
|
|
+ std::this_thread::sleep_for(std::chrono::nanoseconds(nanos));
|
|
|
+ } catch(...) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
bool sleepMillis(i64 millis) {
|
|
@@ -237,9 +263,13 @@ bool sleepMillis(i64 millis) {
|
|
|
}
|
|
|
|
|
|
i64 getNanos(void) {
|
|
|
- struct timespec ts;
|
|
|
- if(timespec_get(&ts, TIME_UTC) == 0 || TIME_GET_FAIL) {
|
|
|
+ try {
|
|
|
+ FAIL_STEP_THROW();
|
|
|
+ using namespace std::chrono;
|
|
|
+ return duration_cast<nanoseconds>(
|
|
|
+ high_resolution_clock::now().time_since_epoch())
|
|
|
+ .count();
|
|
|
+ } catch(std::exception& e) {
|
|
|
return -1;
|
|
|
}
|
|
|
- return (i64)ts.tv_sec * 1'000'000'000L + (i64)ts.tv_nsec;
|
|
|
}
|