From 27061e4c4e723e16797453f473cff7148beecad3 Mon Sep 17 00:00:00 2001 From: Paul Oliver Date: Fri, 31 Jul 2026 04:04:37 +0200 Subject: Adds curses UI --- core/arch_inst.h | 14 +++++++++ core/logger.c | 69 ++++++++++++++++++++++++++++++++----------- core/logger.h | 16 ++++++++-- core/salis.c | 89 ++++++++++++++++++++------------------------------------ core/salis.h | 8 +++-- core/sql.h | 10 ------- core/timer.c | 32 ++++++++++++++++++++ core/timer.h | 14 +++++++++ 8 files changed, 163 insertions(+), 89 deletions(-) create mode 100644 core/arch_inst.h create mode 100644 core/timer.c create mode 100644 core/timer.h (limited to 'core') diff --git a/core/arch_inst.h b/core/arch_inst.h new file mode 100644 index 0000000..e4c80b5 --- /dev/null +++ b/core/arch_inst.h @@ -0,0 +1,14 @@ +// file : core/null/arch_inst.h +// project : Salis-VM +// author : Paul Oliver + +#pragma once + +#if ARCH_INST_COUNT != 0x80 +#error "Value ARCH_INST_COUNT is incorrect" +#endif + +#define ARCH_INST_MASK 0x7f + +wchar_t arch_inst_symbol(uint8_t inst); +const char *arch_inst_mnemonic(uint8_t inst); diff --git a/core/logger.c b/core/logger.c index 47182ce..29f371e 100644 --- a/core/logger.c +++ b/core/logger.c @@ -5,6 +5,7 @@ // index: // [section] includes // [section] macros +// [section] extern globals // [section] definitions // ---------------------------------------------------------------------------- @@ -21,8 +22,6 @@ // ---------------------------------------------------------------------------- // [section] macros // ---------------------------------------------------------------------------- -#define LOG_BUFFER_SIZE 0x800 - #define COLOR_CLEAR "\033[0m" #define COLOR_TRACE "\033[1;34m" #define COLOR_INFO "\033[1;32m" @@ -32,14 +31,20 @@ #define LEVEL_INFO "INFO" #define LEVEL_ATTENTION "ATTENTION" +// ---------------------------------------------------------------------------- +// [section] extern globals +// ---------------------------------------------------------------------------- +void (*log_trace)(const char *format, ...) = log_trace_to_stdout; +void (*log_info)(const char *format, ...) = log_info_to_stdout; +void (*log_attention)(const char *format, ...) = log_attention_to_stdout; + // ---------------------------------------------------------------------------- // [section] definitions // ---------------------------------------------------------------------------- -static void log_default(const char *color_code, const char *level, const char *format, va_list args) { +static void log_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *color_code, const char *level, const char *format, va_list args) { assert(level); assert(format); - char log_buffer[LOG_BUFFER_SIZE]; struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); int msec = (int)(ts.tv_nsec / 1000000l); @@ -47,9 +52,9 @@ static void log_default(const char *color_code, const char *level, const char *f pid_t pid = getpid(); int rem = snprintf( - log_buffer, + buffer, LOG_BUFFER_SIZE, - "\r%s%d-%02d-%02d %02d:%02d:%02d.%03d %07d [%s]%s ", + "%s%d-%02d-%02d %02d:%02d:%02d.%03d %07d [%s]%s ", color_code ? color_code : "", tm.tm_year + 1900, tm.tm_mon + 1, @@ -63,36 +68,66 @@ static void log_default(const char *color_code, const char *level, const char *f color_code ? COLOR_CLEAR : "" ); - vsnprintf(log_buffer + rem, LOG_BUFFER_SIZE - rem, format, args); - printf("%s\n", log_buffer); - fflush(stdout); + vsnprintf(buffer + rem, LOG_BUFFER_SIZE - rem, format, args); } -void log_trace(const char *format, ...) { +void log_trace_to_stdout(const char *format, ...) { assert(format); + (void)format; #if defined(LOG_TRACE) va_list args; va_start(args, format); - log_default(COLOR_TRACE, LEVEL_TRACE, format, args); + char buffer[LOG_BUFFER_SIZE]; + log_to_buffer(buffer, COLOR_TRACE, LEVEL_TRACE, format, args); + printf("\r%s\n", buffer); + fflush(stdout); va_end(args); -#else - (void)format; #endif } -void log_info(const char *format, ...) { +void log_info_to_stdout(const char *format, ...) { assert(format); va_list args; va_start(args, format); - log_default(COLOR_INFO, LEVEL_INFO, format, args); + char buffer[LOG_BUFFER_SIZE]; + log_to_buffer(buffer, COLOR_INFO, LEVEL_INFO, format, args); + printf("\r%s\n", buffer); + fflush(stdout); va_end(args); } -void log_attention(const char *format, ...) { +void log_attention_to_stdout(const char *format, ...) { assert(format); va_list args; va_start(args, format); - log_default(COLOR_ATTENTION, LEVEL_ATTENTION, format, args); + char buffer[LOG_BUFFER_SIZE]; + log_to_buffer(buffer, COLOR_ATTENTION, LEVEL_ATTENTION, format, args); + printf("\r%s\n", buffer); + fflush(stdout); va_end(args); } + +void vlog_trace_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *format, va_list args) { + assert(format); + assert(args); + (void)buffer; + (void)format; + (void)args; + +#if defined(LOG_TRACE) + log_to_buffer(buffer, NULL, LEVEL_TRACE, format, args); +#endif +} + +void vlog_info_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *format, va_list args) { + assert(format); + assert(args); + log_to_buffer(buffer, NULL, LEVEL_INFO, format, args); +} + +void vlog_attention_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *format, va_list args) { + assert(format); + assert(args); + log_to_buffer(buffer, NULL, LEVEL_ATTENTION, format, args); +} diff --git a/core/logger.h b/core/logger.h index e0da38b..e31cba5 100644 --- a/core/logger.h +++ b/core/logger.h @@ -4,6 +4,16 @@ #pragma once -void log_trace(const char *format, ...); -void log_info(const char *format, ...); -void log_attention(const char *format, ...); +#define LOG_BUFFER_SIZE 0x800 + +extern void (*log_trace)(const char *format, ...); +extern void (*log_info)(const char *format, ...); +extern void (*log_attention)(const char *format, ...); + +void log_trace_to_stdout(const char *format, ...); +void log_info_to_stdout(const char *format, ...); +void log_attention_to_stdout(const char *format, ...); + +void vlog_trace_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *format, va_list args); +void vlog_info_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *format, va_list args); +void vlog_attention_to_buffer(char buffer[LOG_BUFFER_SIZE], const char *format, va_list args); diff --git a/core/salis.c b/core/salis.c index 6cc0725..da9b1b0 100644 --- a/core/salis.c +++ b/core/salis.c @@ -37,10 +37,6 @@ // ---------------------------------------------------------------------------- // [section] macros // ---------------------------------------------------------------------------- -#define INST_MASK 0x7f -#define IPCM_FLAG 0x80 -#define MALL_FLAG 0x80 - #define STEP_GROUP_TIME_MIN_MS 0x400 #define STEP_GROUP_TIME_MAX_MS 0x800 @@ -50,13 +46,13 @@ struct Core g_cores[CORES]; uint64_t g_step; uint64_t g_sync; -const struct Proc g_null_proc; +static const struct Proc g_null_proc; -char g_asav_pbuf[AUTOSAVE_NAME_LEN]; -char g_evas_pbuf[EVA_SAVE_NAME_LEN]; +static char g_asav_pbuf[AUTOSAVE_NAME_LEN]; +static char g_evas_pbuf[EVA_SAVE_NAME_LEN]; -atomic_bool g_running; -thrd_t g_thrd; +static atomic_bool g_running; +static thrd_t g_thrd; // ---------------------------------------------------------------------------- // [section] memory vector functions @@ -71,10 +67,10 @@ bool mvec_is_alloc(const struct Core *core, uint64_t addr) { assert(core); #if defined(ARCH_SPEC_MVEC_LOOP) - return core->mvec[mvec_loop(addr)] & MALL_FLAG ? true : false; + return core->mvec[mvec_loop(addr)] & SALIS_MALL_FLAG ? true : false; #else if (addr < MVEC_SIZE) { - return core->mvec[addr] & MALL_FLAG ? true : false; + return core->mvec[addr] & SALIS_MALL_FLAG ? true : false; } else { return true; } @@ -92,7 +88,7 @@ void mvec_alloc(struct Core *core, uint64_t addr) { uint64_t loop_addr = addr; #endif - core->mvec[loop_addr] |= MALL_FLAG; + core->mvec[loop_addr] |= SALIS_MALL_FLAG; core->aeva.data[loop_addr]++; core->mall++; } @@ -109,33 +105,19 @@ void mvec_free(struct Core *core, uint64_t addr) { uint64_t loop_addr = addr; #endif - core->mvec[loop_addr] ^= MALL_FLAG; + core->mvec[loop_addr] ^= SALIS_MALL_FLAG; core->aeva.data[loop_addr]++; core->mall--; } -uint8_t mvec_get_byte(const struct Core *core, uint64_t addr) { - assert(core); - -#if defined(ARCH_SPEC_MVEC_LOOP) - return core->mvec[mvec_loop(addr)]; -#else - if (addr < MVEC_SIZE) { - return core->mvec[addr]; - } else { - return 0; - } -#endif -} - uint8_t mvec_get_inst(const struct Core *core, uint64_t addr) { assert(core); #if defined(ARCH_SPEC_MVEC_LOOP) - return core->mvec[mvec_loop(addr)] & INST_MASK; + return core->mvec[mvec_loop(addr)] & ARCH_INST_MASK; #else if (addr < MVEC_SIZE) { - return core->mvec[addr] & INST_MASK; + return core->mvec[addr] & ARCH_INST_MASK; } else { return 0; } @@ -144,14 +126,14 @@ uint8_t mvec_get_inst(const struct Core *core, uint64_t addr) { void mvec_set_inst(struct Core *core, uint64_t addr, uint8_t inst) { assert(core); - assert(inst < ARCH_INST_CAP); + assert(inst < ARCH_INST_COUNT); #if defined(ARCH_SPEC_MVEC_LOOP) - core->mvec[mvec_loop(addr)] &= MALL_FLAG; + core->mvec[mvec_loop(addr)] &= SALIS_MALL_FLAG; core->mvec[mvec_loop(addr)] |= inst; #else assert(addr < MVEC_SIZE); - core->mvec[addr] &= MALL_FLAG; + core->mvec[addr] &= SALIS_MALL_FLAG; core->mvec[addr] |= inst; #endif } @@ -160,7 +142,7 @@ void mvec_set_inst(struct Core *core, uint64_t addr, uint8_t inst) { void mvec_flip_bit(struct Core *core, uint64_t addr, int bit) { assert(core); assert(bit < 8); - core->mvec[addr] ^= (1 << bit) & INST_MASK; + core->mvec[addr] ^= (1 << bit) & ARCH_INST_MASK; } #endif @@ -250,7 +232,7 @@ void muta_cosmic_ray(struct Core *core) { #if defined(ARCH_SPEC_MUTA_FLIP) mvec_flip_bit(core, a, (int)(b % 8)); #else - mvec_set_inst(core, a, b & INST_MASK); + mvec_set_inst(core, a, b & ARCH_INST_MASK); #endif } } @@ -474,8 +456,8 @@ static void core_pull_ipcm(struct Core *core) { uint8_t *iinst = &core->iviv[core->ivpt]; uint64_t *iaddr = &core->ivav[core->ivpt]; - if ((*iinst & IPCM_FLAG) != 0) { - mvec_set_inst(core, *iaddr, *iinst & INST_MASK); + if ((*iinst & SALIS_IPCM_FLAG) != 0) { + mvec_set_inst(core, *iaddr, *iinst & ARCH_INST_MASK); *iinst = 0; *iaddr = 0; } @@ -487,12 +469,12 @@ static void core_pull_ipcm(struct Core *core) { void core_push_ipcm(struct Core *core, uint8_t inst, uint64_t addr) { assert(core); assert(core->ivpt < SYNC_INTERVAL); - assert((inst & IPCM_FLAG) == 0); + assert((inst & SALIS_IPCM_FLAG) == 0); uint8_t *iinst = &core->iviv[core->ivpt]; uint64_t *iaddr = &core->ivav[core->ivpt]; assert(*iinst == 0); assert(*iaddr == 0); - *iinst = inst | IPCM_FLAG; + *iinst = inst | SALIS_IPCM_FLAG; *iaddr = addr; } @@ -622,7 +604,7 @@ static void core_validate(struct Core *core) { for (uint64_t i = 0; i < SYNC_INTERVAL; i++) { uint8_t iinst = core->iviv[i]; - if ((iinst & IPCM_FLAG) == 0) { + if ((iinst & SALIS_IPCM_FLAG) == 0) { uint64_t iaddr = core->ivav[i]; assert(iinst == 0); assert(iaddr == 0); @@ -997,10 +979,6 @@ static int salis_thread(void *data) { assert(atomic_load_explicit(&g_running, memory_order_relaxed)); (void)data; - struct timespec time_start; - clock_gettime(CLOCK_MONOTONIC_COARSE, &time_start); - uint64_t step_start = g_step; - while (atomic_load_explicit(&g_running, memory_order_relaxed)) { log_trace("Launching core threads"); @@ -1036,19 +1014,6 @@ static int salis_thread(void *data) { #if !defined(NDEBUG) salis_validate(); #endif - - // Log simulation steps/s - struct timespec time_end; - clock_gettime(CLOCK_MONOTONIC_COARSE, &time_end); - int time_delta = time_end.tv_sec - time_start.tv_sec; - - if (time_delta > 0) { - uint64_t step_end = g_step; - uint64_t step_delta = step_end - step_start; - time_start = time_end; - step_start = step_end; - log_info("Running simulation @%#018lx steps/s", step_delta); - } } return 0; @@ -1067,12 +1032,23 @@ void salis_join(void) { thrd_join(g_thrd, NULL); } +void salis_wait(void) { + assert(!atomic_load_explicit(&g_running, memory_order_relaxed)); + log_trace("Waiting for main thread"); + thrd_join(g_thrd, NULL); +} + void salis_signal_stop(void) { assert(atomic_load_explicit(&g_running, memory_order_relaxed)); log_trace("Signaling main thread to stop"); atomic_store_explicit(&g_running, false, memory_order_relaxed); } +void salis_signal_stop_no_check(void) { + log_trace("Signaling main thread to stop"); + atomic_store_explicit(&g_running, false, memory_order_relaxed); +} + void salis_step(uint64_t steps) { assert(!atomic_load_explicit(&g_running, memory_order_relaxed)); log_trace("Stepping simulation %lu times", steps); @@ -1083,7 +1059,6 @@ void salis_step(uint64_t steps) { } g_step++; - salis_check_intervals(); } diff --git a/core/salis.h b/core/salis.h index e61752b..f144698 100644 --- a/core/salis.h +++ b/core/salis.h @@ -16,8 +16,10 @@ // ---------------------------------------------------------------------------- // [section] macros // ---------------------------------------------------------------------------- -#define SALIS_UINT64_HALF 0x8000000000000000ul #define SALIS_EVENT_ARRAY_SIZE_COL_MARKER "_evasize_" +#define SALIS_IPCM_FLAG 0x80 +#define SALIS_MALL_FLAG 0x80 +#define SALIS_UINT64_HALF 0x8000000000000000ul // ---------------------------------------------------------------------------- // [section] structs @@ -83,6 +85,7 @@ struct Core { // ---------------------------------------------------------------------------- extern struct Core g_cores[CORES]; extern uint64_t g_step; +extern uint64_t g_sync; // ---------------------------------------------------------------------------- // [section] memory vector declarations @@ -95,7 +98,6 @@ bool mvec_is_alloc(const struct Core *core, uint64_t addr); void mvec_alloc(struct Core *core, uint64_t addr); void mvec_free(struct Core *core, uint64_t addr); -uint8_t mvec_get_byte(const struct Core *core, uint64_t addr); uint8_t mvec_get_inst(const struct Core *core, uint64_t addr); void mvec_set_inst(struct Core *core, uint64_t addr, uint8_t inst); @@ -142,6 +144,8 @@ void salis_load(void); void salis_start(void); void salis_join(void); +void salis_wait(void); void salis_signal_stop(void); +void salis_signal_stop_no_check(void); void salis_step(uint64_t steps); void salis_free(void); diff --git a/core/sql.h b/core/sql.h index 675d096..0fc6295 100644 --- a/core/sql.h +++ b/core/sql.h @@ -4,18 +4,8 @@ #pragma once -// index: -// [section] extern globals -// [section] declarations - -// ---------------------------------------------------------------------------- -// [section] extern globals -// ---------------------------------------------------------------------------- extern sqlite3 *g_sim_db; -// ---------------------------------------------------------------------------- -// [section] declarations -// ---------------------------------------------------------------------------- void sql_open(void); void sql_close(void); void sql_exec(void (*callback)(sqlite3_stmt *sql_stmt, void *data), void *data, const char *sql_format, ...); diff --git a/core/timer.c b/core/timer.c new file mode 100644 index 0000000..21f5c33 --- /dev/null +++ b/core/timer.c @@ -0,0 +1,32 @@ +// file : core/timer.c +// project : Salis-VM +// author : Paul Oliver + +#include +#include +#include +#include +#include + +#include "arch_spec.h" +#include "compress.h" +#include "salis.h" +#include "timer.h" + +void timer_reset(struct Timer *timer) { + assert(timer); + timer->step_start = g_step; + clock_gettime(CLOCK_MONOTONIC_COARSE, &timer->time_start); + timer->steps_per_sec = 0.f; +} + +void timer_measure(struct Timer *timer) { + assert(timer); + uint64_t step_end = g_step; + struct timespec time_end; + clock_gettime(CLOCK_MONOTONIC_COARSE, &time_end); + float step_delta = (float)(step_end - timer->step_start); + float time_delta = (float)(time_end.tv_sec - timer->time_start.tv_sec); + time_delta += (float)(time_end.tv_nsec - timer->time_start.tv_nsec) / 1000000000.f; + timer->steps_per_sec = step_delta / time_delta; +} diff --git a/core/timer.h b/core/timer.h new file mode 100644 index 0000000..8778831 --- /dev/null +++ b/core/timer.h @@ -0,0 +1,14 @@ +// file : core/timer.h +// project : Salis-VM +// author : Paul Oliver + +#pragma once + +struct Timer { + uint64_t step_start; + struct timespec time_start; + float steps_per_sec; +}; + +void timer_reset(struct Timer *timer); +void timer_measure(struct Timer *timer); -- cgit v1.2.1