summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2026-07-31 04:04:37 +0200
committerPaul Oliver <contact@pauloliver.dev>2026-08-05 00:20:29 +0200
commit3ede06f803cfa0173d246695527d26440fd555d5 (patch)
tree4283b35c149188d9f596d38435c0940e840571c8 /core
parent8a4563d6d0c9e81fdaa42f6f760cae2b49cad431 (diff)
Adds curses UIHEADmaster
Diffstat (limited to 'core')
-rw-r--r--core/arch_inst.h11
-rw-r--r--core/logger.c69
-rw-r--r--core/logger.h16
-rw-r--r--core/salis.c85
-rw-r--r--core/salis.h7
5 files changed, 121 insertions, 67 deletions
diff --git a/core/arch_inst.h b/core/arch_inst.h
new file mode 100644
index 0000000..d06c9c8
--- /dev/null
+++ b/core/arch_inst.h
@@ -0,0 +1,11 @@
+// file : core/null/arch_inst.h
+// project : Salis-VM
+// author : Paul Oliver <contact@pauloliver.dev>
+
+#pragma once
+
+#define ARCH_INST_COUNT 0x80
+#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"
@@ -33,13 +32,19 @@
#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..99d26a2 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,9 +979,11 @@ static int salis_thread(void *data) {
assert(atomic_load_explicit(&g_running, memory_order_relaxed));
(void)data;
+#if defined(SALIS_LOG_TIME)
+ uint64_t step_start = g_step;
struct timespec time_start;
clock_gettime(CLOCK_MONOTONIC_COARSE, &time_start);
- uint64_t step_start = g_step;
+#endif
while (atomic_load_explicit(&g_running, memory_order_relaxed)) {
log_trace("Launching core threads");
@@ -1037,18 +1021,24 @@ static int salis_thread(void *data) {
salis_validate();
#endif
+#if defined(SALIS_LOG_TIME)
// Log simulation steps/s
+ // This will only trigger in situations where `salis_thread()`
+ // is let to run for more than 1 second.
struct timespec time_end;
clock_gettime(CLOCK_MONOTONIC_COARSE, &time_end);
- int time_delta = time_end.tv_sec - time_start.tv_sec;
+ float time_delta = (float)(time_end.tv_sec - time_start.tv_sec);
+ time_delta += (float)(time_end.tv_nsec - time_start.tv_nsec) / 1000000000.f;
- if (time_delta > 0) {
+ if (time_delta > 1.f) {
uint64_t step_end = g_step;
- uint64_t step_delta = step_end - step_start;
+ float step_delta = (float)(step_end - step_start);
+ float steps_per_sec = step_delta / time_delta;
time_start = time_end;
step_start = step_end;
- log_info("Running simulation @%#018lx steps/s", step_delta);
+ log_info("Running simulation @%#018lx steps/s", (uint64_t)steps_per_sec);
}
+#endif
}
return 0;
@@ -1067,6 +1057,12 @@ 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");
@@ -1083,7 +1079,6 @@ void salis_step(uint64_t steps) {
}
g_step++;
-
salis_check_intervals();
}
diff --git a/core/salis.h b/core/salis.h
index e61752b..27adab1 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,7 @@ void salis_load(void);
void salis_start(void);
void salis_join(void);
+void salis_wait(void);
void salis_signal_stop(void);
void salis_step(uint64_t steps);
void salis_free(void);