mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 03:08:41 +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;
|
||||
};
|
||||
|
||||
// @todo implement memory usage visualization
|
||||
|
||||
inline
|
||||
void buffer_alloc(BufferMemory* buf, uint64 size, int alignment = 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@
|
|||
#define TOS_MEMORY_RING_MEMORY_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -9,8 +9,8 @@
|
|||
#ifndef TOS_UTILS_TEST_UTILS_H
|
||||
#define TOS_UTILS_TEST_UTILS_H
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
#if _WIN32
|
||||
|
|
@ -19,12 +19,9 @@
|
|||
#include <x86intrin.h>
|
||||
#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) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user