mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 11:18:40 +00:00
implement basic logging system (timings + text)
This commit is contained in:
parent
f3cd6bb31f
commit
9374b5aa2c
135
log/Log.h
Normal file
135
log/Log.h
Normal file
|
|
@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
@ -25,8 +25,6 @@ struct BufferMemory {
|
||||||
int alignment;
|
int alignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @todo implement memory usage visualization
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void buffer_alloc(BufferMemory* buf, uint64 size, int alignment = 1)
|
void buffer_alloc(BufferMemory* buf, uint64 size, int alignment = 1)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ struct ChunkMemory {
|
||||||
uint64* free;
|
uint64* free;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @todo implement memory usage visualization
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int alignment = 1)
|
void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int alignment = 1)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ struct DebugMemory {
|
||||||
#define DEBUG_MEMORY_RESET(mem) debug_memory_reset((mem))
|
#define DEBUG_MEMORY_RESET(mem) debug_memory_reset((mem))
|
||||||
#define DEBUG_MEMORY_FREE(mem, start, end) debug_memory_add_range((mem), (start), (end))
|
#define DEBUG_MEMORY_FREE(mem, start, end) debug_memory_add_range((mem), (start), (end))
|
||||||
#else
|
#else
|
||||||
#define DEBUG_MEMORY(mem, start, end) ((void)0)
|
#define DEBUG_MEMORY(mem, start, end) ((void) 0)
|
||||||
#define DEBUG_MEMORY_RESET(mem) ((void)0)
|
#define DEBUG_MEMORY_RESET(mem) ((void) 0)
|
||||||
#define DEBUG_MEMORY_FREE(mem, start, end) ((void)0)
|
#define DEBUG_MEMORY_FREE(mem, start, end) ((void) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void debug_memory_resize(DebugMemory* mem)
|
void debug_memory_resize(DebugMemory* mem)
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@
|
||||||
#define TOS_MEMORY_RING_MEMORY_H
|
#define TOS_MEMORY_RING_MEMORY_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../stdlib/Types.h"
|
#include "../stdlib/Types.h"
|
||||||
#include "../utils/MathUtils.h"
|
#include "../utils/MathUtils.h"
|
||||||
#include "../utils/TestUtils.h"
|
#include "../utils/TestUtils.h"
|
||||||
|
|
||||||
#include "Allocation.h"
|
#include "Allocation.h"
|
||||||
#include "BufferMemory.h"
|
#include "BufferMemory.h"
|
||||||
#include "DebugMemory.h"
|
#include "DebugMemory.h"
|
||||||
|
|
@ -37,8 +39,6 @@ struct RingMemory {
|
||||||
uint64 end;
|
uint64 end;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @todo implement memory usage visualization
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void ring_alloc(RingMemory* ring, uint64 size, int alignment = 1)
|
void ring_alloc(RingMemory* ring, uint64 size, int alignment = 1)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,11 @@ file_copy(const char* src, const char* dst)
|
||||||
{
|
{
|
||||||
CopyFileA((LPCSTR) src, (LPCSTR) dst, false);
|
CopyFileA((LPCSTR) src, (LPCSTR) dst, false);
|
||||||
}
|
}
|
||||||
|
inline
|
||||||
|
void close_handle(HANDLE fp)
|
||||||
|
{
|
||||||
|
CloseHandle(fp);
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
HANDLE get_append_handle(const char* path)
|
HANDLE get_append_handle(const char* path)
|
||||||
|
|
@ -312,7 +317,7 @@ HANDLE get_append_handle(const char* path)
|
||||||
FILE_APPEND_DATA,
|
FILE_APPEND_DATA,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_ALWAYS,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
@ -321,7 +326,7 @@ HANDLE get_append_handle(const char* path)
|
||||||
FILE_APPEND_DATA,
|
FILE_APPEND_DATA,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_ALWAYS,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
@ -410,7 +415,6 @@ file_append(HANDLE fp, const char* file, size_t length)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(fp);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -490,43 +494,4 @@ inline void self_path(char* path)
|
||||||
GetModuleFileNameA(NULL, (LPSTR) path, MAX_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
|
#endif
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
#ifndef TOS_UTILS_TEST_UTILS_H
|
#ifndef TOS_UTILS_TEST_UTILS_H
|
||||||
#define TOS_UTILS_TEST_UTILS_H
|
#define TOS_UTILS_TEST_UTILS_H
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
#include "../stdlib/Types.h"
|
#include "../stdlib/Types.h"
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
|
@ -19,12 +19,9 @@
|
||||||
#include <x86intrin.h>
|
#include <x86intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_LOG_LENGTH 128
|
|
||||||
|
|
||||||
global_persist uint64 performance_count_frequency;
|
global_persist uint64 performance_count_frequency;
|
||||||
struct TimingStat {
|
struct TimingStat {
|
||||||
uint64 old_tick_count;
|
uint64 old_tick_count;
|
||||||
uint64 new_tick_count;
|
|
||||||
|
|
||||||
uint64 delta_tick;
|
uint64 delta_tick;
|
||||||
double delta_time;
|
double delta_time;
|
||||||
|
|
@ -35,12 +32,12 @@ struct TimingStat {
|
||||||
inline
|
inline
|
||||||
void update_timing_stat(TimingStat *stat)
|
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->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.
|
// 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 UPDATE_TIMING_STAT(stat) update_timing_stat(stat)
|
||||||
#define DEBUG_OUTPUT(str) OutputDebugStringA(str)
|
#define DEBUG_OUTPUT(str) OutputDebugStringA(str)
|
||||||
#else
|
#else
|
||||||
#define UPDATE_TIMING_STAT(stat) ((void)0)
|
#define UPDATE_TIMING_STAT(stat) ((void) 0)
|
||||||
#define DEBUG_OUTPUT(str) ((void)0)
|
#define DEBUG_OUTPUT(str) ((void) 0)
|
||||||
#endif
|
#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) \
|
#define ASSERT_EQUALS(a, b, t1, t2) \
|
||||||
({ \
|
({ \
|
||||||
if ((a) == (b)) { \
|
if ((a) == (b)) { \
|
||||||
|
|
@ -132,7 +116,7 @@ void profile_function(const char* func_name, void (*func)(void*), void* data, in
|
||||||
*(volatile int *)0 = 0; \
|
*(volatile int *)0 = 0; \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define ASSERT_SIMPLE(a) ((void)0)
|
#define ASSERT_SIMPLE(a) ((void) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ASSERT_TRUE(a) \
|
#define ASSERT_TRUE(a) \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user