diff --git a/log/Log.h b/log/Log.h new file mode 100644 index 0000000..82d1e62 --- /dev/null +++ b/log/Log.h @@ -0,0 +1,135 @@ +/** + * Jingga + * + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_PLATFORM_WIN32_LOG_H +#define TOS_PLATFORM_WIN32_LOG_H + +#include +#include + +#include "../stdlib/Types.h" +#include "../platform/win32/UtilsWin32.h" +#include "../memory/RingMemory.h" + +#ifndef LOG_LEVEL + #define LOG_LEVEL 0 +#endif + +#ifndef MAX_LOG_LENGTH + #define MAX_LOG_LENGTH 128 +#endif + +enum LogDataType { + LOG_DATA_VOID, + LOG_DATA_INT32, + LOG_DATA_UINT32, + LOG_DATA_INT64, + LOG_DATA_UINT64, + LOG_DATA_CHAR, + LOG_DATA_CHAR_STR, + LOG_DATA_FLOAT32, + LOG_DATA_FLOAT64 +}; + +void log_to_file(RingMemory* logs, HANDLE fp) +{ + // we don't log an empty log pool + if (logs->pos == 0 || !fp) { + return; + } + + file_append(fp, (char *) logs->memory, logs->pos - 1); + memset(logs->memory, 0, logs->size); + + // reset log position to start of memory pool + logs->pos = 0; + logs->start = 0; +} + +void log(RingMemory* logs, const char* str, HANDLE fp = NULL, bool should_log = true, bool save = false) +{ + if (!should_log) { + return; + } + + size_t length = strlen(str); + ASSERT_SIMPLE(length < MAX_LOG_LENGTH); + + char* temp = (char *) ring_get_memory(logs, length + 1); + strcpy(temp, str); + temp[length] = '\0'; + + if (fp != NULL && (save || logs->size - logs->pos < MAX_LOG_LENGTH)) { + log_to_file(logs, fp); + } +} + +void log(RingMemory* logs, const char* format, LogDataType data_type, void* data, HANDLE fp = NULL, bool should_log = true, bool save = false) +{ + if (!should_log) { + return; + } + + if (data_type == LOG_DATA_VOID) { + log(logs, format, fp, true); + } + + char* temp = (char *) ring_get_memory(logs, MAX_LOG_LENGTH); + + switch (data_type) { + case LOG_DATA_INT32: { + sprintf(temp, format, *((int32 *) data)); + } break; + case LOG_DATA_UINT32: { + sprintf(temp, format, *((uint32 *) data)); + } break; + case LOG_DATA_INT64: { + sprintf(temp, format, *((int64 *) data)); + } break; + case LOG_DATA_UINT64: { + sprintf(temp, format, *((uint64 *) data)); + } break; + case LOG_DATA_CHAR: { + sprintf(temp, format, *((char *) data)); + } break; + case LOG_DATA_CHAR_STR: { + sprintf(temp, format, *((char *) data)); + } break; + case LOG_DATA_FLOAT32: { + sprintf(temp, format, *((f32 *) data)); + } break; + case LOG_DATA_FLOAT64: { + sprintf(temp, format, *((f64 *) data)); + } break; + } + + if (fp != NULL && (save || logs->size - logs->pos < MAX_LOG_LENGTH)) { + log_to_file(logs, fp); + } +} + +#if (LOG_LEVEL == 0) + // Don't perform any logging at log level 0 + #define LOG(logs, str, fp, should_log, save) ((void) 0) + #define LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) ((void) 0) + #define LOG_TO_FILE(logs, fp, should_log, save) ((void) 0) +#else + #define LOG(logs, str, fp, should_log, save) log((logs), (str), (fp), (should_log), (save)) + #define LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) log((logs), (format), (data_type), (data), (fp), (should_log), (save)) + #define LOG_TO_FILE(logs, fp, should_log, save) log_to_file((logs), (fp), (should_log), (save)) +#endif + +#if DEBUG + #define DEBUG_LOG(logs, str, fp, should_log, save) log((logs), (str), (fp), (should_log), (save)) + #define DEBUG_LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) log((logs), (format), (data_type), (data), (fp), (should_log), (save)) +#else + #define DEBUG_LOG(logs, str, fp, should_log, save) ((void) 0) + #define DEBUG_LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) ((void) 0) +#endif + +#endif \ No newline at end of file diff --git a/memory/BufferMemory.h b/memory/BufferMemory.h index 0a47415..7eabb01 100644 --- a/memory/BufferMemory.h +++ b/memory/BufferMemory.h @@ -25,8 +25,6 @@ struct BufferMemory { int alignment; }; -// @todo implement memory usage visualization - inline void buffer_alloc(BufferMemory* buf, uint64 size, int alignment = 1) { diff --git a/memory/ChunkMemory.h b/memory/ChunkMemory.h index 17c72ae..77bd653 100644 --- a/memory/ChunkMemory.h +++ b/memory/ChunkMemory.h @@ -29,8 +29,6 @@ struct ChunkMemory { uint64* free; }; -// @todo implement memory usage visualization - inline void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int alignment = 1) { diff --git a/memory/DebugMemory.h b/memory/DebugMemory.h index b09ac23..196fb51 100644 --- a/memory/DebugMemory.h +++ b/memory/DebugMemory.h @@ -33,9 +33,9 @@ struct DebugMemory { #define DEBUG_MEMORY_RESET(mem) debug_memory_reset((mem)) #define DEBUG_MEMORY_FREE(mem, start, end) debug_memory_add_range((mem), (start), (end)) #else - #define DEBUG_MEMORY(mem, start, end) ((void)0) - #define DEBUG_MEMORY_RESET(mem) ((void)0) - #define DEBUG_MEMORY_FREE(mem, start, end) ((void)0) + #define DEBUG_MEMORY(mem, start, end) ((void) 0) + #define DEBUG_MEMORY_RESET(mem) ((void) 0) + #define DEBUG_MEMORY_FREE(mem, start, end) ((void) 0) #endif void debug_memory_resize(DebugMemory* mem) diff --git a/memory/RingMemory.h b/memory/RingMemory.h index 36cb9bb..5c7ea92 100644 --- a/memory/RingMemory.h +++ b/memory/RingMemory.h @@ -10,9 +10,11 @@ #define TOS_MEMORY_RING_MEMORY_H #include + #include "../stdlib/Types.h" #include "../utils/MathUtils.h" #include "../utils/TestUtils.h" + #include "Allocation.h" #include "BufferMemory.h" #include "DebugMemory.h" @@ -37,8 +39,6 @@ struct RingMemory { uint64 end; }; -// @todo implement memory usage visualization - inline void ring_alloc(RingMemory* ring, uint64 size, int alignment = 1) { diff --git a/platform/win32/UtilsWin32.h b/platform/win32/UtilsWin32.h index d5bc482..42178d0 100644 --- a/platform/win32/UtilsWin32.h +++ b/platform/win32/UtilsWin32.h @@ -299,6 +299,11 @@ file_copy(const char* src, const char* dst) { CopyFileA((LPCSTR) src, (LPCSTR) dst, false); } +inline +void close_handle(HANDLE fp) +{ + CloseHandle(fp); +} inline HANDLE get_append_handle(const char* path) @@ -312,7 +317,7 @@ HANDLE get_append_handle(const char* path) FILE_APPEND_DATA, 0, NULL, - OPEN_EXISTING, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); @@ -321,7 +326,7 @@ HANDLE get_append_handle(const char* path) FILE_APPEND_DATA, 0, NULL, - OPEN_EXISTING, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); @@ -410,7 +415,6 @@ file_append(HANDLE fp, const char* file, size_t length) return false; } - CloseHandle(fp); return true; } @@ -490,43 +494,4 @@ inline void self_path(char* path) GetModuleFileNameA(NULL, (LPSTR) path, MAX_PATH); } -void log_to_file(RingMemory* logs, HANDLE fp) -{ - // we don't log an empty log pool - if (logs->pos == 0) { - return; - } - - file_append(fp, (char *) logs->memory, logs->size); - memset(logs->memory, 0, logs->size); - - // reset log position to start of memory pool - logs->pos = 0; - logs->start = 0; -} - -// snprintf(logs->memory + logs->pos * MAX_LOG_LENGTH, MAX_LOG_LENGTH, "My text %s", str1); -void log(RingMemory* logs, const char* str, HANDLE fp = NULL) -{ - size_t length = strlen(str); - ASSERT_SIMPLE(length < MAX_LOG_LENGTH); - - char* temp = (char *) ring_get_memory(logs, length + 1); - strcpy(temp, str); - temp[length] = '\0'; - - if (fp != NULL && logs->size - logs->pos < MAX_LOG_LENGTH) { - log_to_file(logs, fp); - } -} - -#if (LOG_LEVEL == 0) - // Don't perform any logging at log level 0 - #define LOG(logs, str, fp) ((void)0) - #define LOG_TO_FILE(logs, fp) ((void)0) -#else - #define LOG(logs, str, fp) log(logs, str, fp); - #define LOG_TO_FILE(logs, fp) log_to_file(logs, fp); -#endif - #endif \ No newline at end of file diff --git a/utils/TestUtils.h b/utils/TestUtils.h index 0aaa7f6..83bd0cc 100644 --- a/utils/TestUtils.h +++ b/utils/TestUtils.h @@ -9,8 +9,8 @@ #ifndef TOS_UTILS_TEST_UTILS_H #define TOS_UTILS_TEST_UTILS_H -#include #include +#include #include "../stdlib/Types.h" #if _WIN32 @@ -19,12 +19,9 @@ #include #endif -#define MAX_LOG_LENGTH 128 - global_persist uint64 performance_count_frequency; struct TimingStat { uint64 old_tick_count; - uint64 new_tick_count; uint64 delta_tick; double delta_time; @@ -35,12 +32,12 @@ struct TimingStat { inline void update_timing_stat(TimingStat *stat) { - stat->new_tick_count = __rdtsc(); + uint64 new_tick_count = __rdtsc(); - stat->delta_tick = stat->new_tick_count - stat->old_tick_count; + stat->delta_tick = new_tick_count - stat->old_tick_count; stat->delta_time = (double) stat->delta_tick / (double) performance_count_frequency; - stat->old_tick_count = stat->new_tick_count; + stat->old_tick_count = new_tick_count; } // Sometimes we want to only do logging in debug mode. @@ -49,23 +46,10 @@ void update_timing_stat(TimingStat *stat) #define UPDATE_TIMING_STAT(stat) update_timing_stat(stat) #define DEBUG_OUTPUT(str) OutputDebugStringA(str) #else - #define UPDATE_TIMING_STAT(stat) ((void)0) - #define DEBUG_OUTPUT(str) ((void)0) + #define UPDATE_TIMING_STAT(stat) ((void) 0) + #define DEBUG_OUTPUT(str) ((void) 0) #endif -void profile_function(const char* func_name, void (*func)(void*), void* data, int iterations) -{ - clock_t start = clock(); - for (int i = 0; i < iterations; ++i) { - func(data); - } - - clock_t end = clock(); - double elapsed_time = (double)(end - start) / CLOCKS_PER_SEC; - - printf("Time taken by %s: %f seconds\n", func_name, elapsed_time); -} - #define ASSERT_EQUALS(a, b, t1, t2) \ ({ \ if ((a) == (b)) { \ @@ -132,7 +116,7 @@ void profile_function(const char* func_name, void (*func)(void*), void* data, in *(volatile int *)0 = 0; \ } #else - #define ASSERT_SIMPLE(a) ((void)0) + #define ASSERT_SIMPLE(a) ((void) 0) #endif #define ASSERT_TRUE(a) \