diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2025-11-22 03:03:11 +0100 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2025-11-24 16:49:04 +0100 |
| commit | c8fc429d9e5ed8ab0566729003d60ef41f578807 (patch) | |
| tree | da0c41a8e2b72ba2f32ee495440793bd73039ccb /ui | |
| parent | 0bc672fe6c263b9894af0cd211d006054215c7a9 (diff) | |
Improves logging system
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/curses/ui.j2.c | 177 | ||||
| -rw-r--r-- | ui/daemon/ui.j2.c | 42 |
2 files changed, 208 insertions, 11 deletions
diff --git a/ui/curses/ui.j2.c b/ui/curses/ui.j2.c index 4370774..9ebd387 100644 --- a/ui/curses/ui.j2.c +++ b/ui/curses/ui.j2.c @@ -11,6 +11,9 @@ {% set proc_field_width = 21 %} {% set proc_page_lines = 12 %} +{% set log_line_size = 1024 %} +{% set log_line_count = 1024 %} + {% macro ctrl(x) %}('{{ x }}' & 0x1f){% endmacro %} {% if not args.optimized %} @@ -27,6 +30,7 @@ enum { PAGE_PROCESS, PAGE_WORLD, PAGE_IPC, + PAGE_LOG, PAGE_COUNT, }; @@ -35,6 +39,7 @@ enum { PAIR_NOUSE, PAIR_NORMAL, PAIR_HEADER, + PAIR_WARN, PAIR_LIVE_PROC, PAIR_SELECTED_PROC, PAIR_FREE_CELL, @@ -72,6 +77,12 @@ bool g_wcursor_mode; int g_wcursor_x; int g_wcursor_y; uint64_t g_wcursor_pointed; +uint64_t g_log_cnt; +unsigned g_log_ptr; +unsigned g_log_scroll; +bool g_log_warns[{{ log_line_count }}]; +time_t g_log_times[{{ log_line_count }}]; +char g_logs[{{ log_line_count }}][{{ log_line_size }}]; uint64_t g_vlin; uint64_t g_vsiz; uint64_t g_vlin_rng; @@ -310,7 +321,7 @@ void gfx_render(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t p } // ---------------------------------------------------------------------------- -// TUI functions +// TUI generic functions // ---------------------------------------------------------------------------- void ui_line_buff_free() { if (g_line_buff) { @@ -387,6 +398,9 @@ void ui_ulx_field(int l, const char *label, uint64_t value) { ui_line(false, l, PAIR_NORMAL, A_NORMAL, "%-4s : %#18lx", label, value); } +// ---------------------------------------------------------------------------- +// Core page functions +// ---------------------------------------------------------------------------- void ui_print_core(int l) { ui_line(false, ++l, PAIR_HEADER, A_BOLD, "CORE [%d]", g_core); ui_ulx_field(++l, "cycl", g_cores[g_core].cycl); @@ -409,6 +423,9 @@ void ui_print_core(int l) { {% endfor %} } +// ---------------------------------------------------------------------------- +// Process page functions +// ---------------------------------------------------------------------------- int ui_proc_pair(uint64_t pix) { if (pix == g_proc_selected) { return PAIR_SELECTED_PROC; @@ -566,6 +583,9 @@ void ui_print_process(int l) { } } +// ---------------------------------------------------------------------------- +// World page functions +// ---------------------------------------------------------------------------- void ui_world_resize() { assert(g_wrld_zoom); @@ -718,6 +738,9 @@ void ui_print_world(int l) { } } +// ---------------------------------------------------------------------------- +// IPC page functions +// ---------------------------------------------------------------------------- void ui_print_ipc_field(int l, uint64_t i, int color) { uint8_t iinst = g_cores[g_core].iviv[i]; uint64_t iaddr = g_cores[g_core].ivav[i]; @@ -771,6 +794,118 @@ void ui_print_ipc(int l) { ui_print_ipc_data(); } +// ---------------------------------------------------------------------------- +// Log page functions +// ---------------------------------------------------------------------------- +void ui_info_impl(const char *format, ...) { + g_log_warns[g_log_ptr] = false; + g_log_times[g_log_ptr] = time(NULL); + + va_list args; + va_start(args, format); + vsnprintf(g_logs[g_log_ptr], {{ log_line_size }}, format, args); + va_end(args); + + g_log_cnt++; + g_log_ptr = (g_log_ptr + 1) % {{ log_line_count }}; +} + +void ui_warn_impl(const char *format, ...) { + g_log_warns[g_log_ptr] = true; + g_log_times[g_log_ptr] = time(NULL); + + va_list args; + va_start(args, format); + vsnprintf(g_logs[g_log_ptr], {{ log_line_size }}, format, args); + va_end(args); + + g_log_cnt++; + g_log_ptr = (g_log_ptr + 1) % {{ log_line_count }}; +} + +void ui_clear_log_line(int line) { + assert(line >= 0 && line < LINES); + move(line, {{ pane_width }}); + clrtoeol(); +} + +void ui_print_log_line(unsigned lptr, int line) { + assert(lptr < {{ log_line_count }}); + assert(line >= 0 && line < LINES); + ui_clear_log_line(line); + + // Prints a log entry + if (strlen(g_logs[lptr])) { + struct tm tm = *localtime(&g_log_times[lptr]); + + // Timestamp + ui_field( + line, + {{ pane_width }}, + PAIR_NORMAL, + A_NORMAL, + "%d-%02d-%02d %02d:%02d:%02d", + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec + ); + + // Level + ui_field( + line, + {{ pane_width }} + 20, + g_log_warns[lptr] ? PAIR_WARN : PAIR_HEADER, + A_NORMAL, + g_log_warns[lptr] ? "WARN:" : "INFO:" + ); + + // Message + ui_field( + line, + {{ pane_width }} + 26, + PAIR_NORMAL, + A_NORMAL, + g_logs[lptr] + ); + } +} + +void ui_print_log(int l) { + l++; + + ui_line(true, l++, PAIR_HEADER, A_BOLD, "LOG"); + ui_ulx_field(l++, "lscr", g_log_scroll); + ui_ulx_field(l++, "lcnt", g_log_cnt); + ui_ulx_field(l++, "lptr", g_log_ptr); + + unsigned lptr = g_log_ptr; + int line = LINES + g_log_scroll; + + while (line) { + lptr = (lptr - 1 + {{ log_line_count }}) % {{ log_line_count }}; + line--; + + if (line < LINES) { + ui_print_log_line(lptr, line); + } + + if (lptr == g_log_ptr) { + break; + } + } + + while (line) { + line--; + ui_clear_log_line(line); + } +} + +// ---------------------------------------------------------------------------- +// Main print function +// ---------------------------------------------------------------------------- void ui_print() { int l = 1; @@ -799,11 +934,17 @@ void ui_print() { case PAGE_IPC: ui_print_ipc(l); break; + case PAGE_LOG: + ui_print_log(l); + break; default: break; } } +// ---------------------------------------------------------------------------- +// Control function +// ---------------------------------------------------------------------------- void ev_vscroll(int ev) { switch (g_page) { case PAGE_PROCESS: @@ -879,6 +1020,28 @@ void ev_vscroll(int ev) { } break; + case PAGE_LOG: + switch (ev) { + case 'W': + g_log_scroll += LINES; + g_log_scroll = g_log_scroll >= {{ log_line_count }} ? {{ log_line_count }} - 1 : g_log_scroll; + break; + case 'S': + g_log_scroll -= g_log_scroll < (uint64_t)LINES ? g_log_scroll : (uint64_t)LINES; + break; + case 'w': + g_log_scroll += 1; + g_log_scroll = g_log_scroll >= {{ log_line_count }} ? {{ log_line_count }} - 1 : g_log_scroll; + break; + case 's': + g_log_scroll -= g_log_scroll ? 1 : 0; + break; + case 'q': + g_log_scroll = 0; + break; + } + + break; default: break; } @@ -1037,7 +1200,7 @@ void ev_handle() { break; case KEY_SLEFT: clear(); - g_core = (g_core - 1) % {{ args.cores }}; + g_core = (g_core + {{ args.cores }} - 1) % {{ args.cores }}; break; case KEY_SRIGHT: clear(); @@ -1045,7 +1208,7 @@ void ev_handle() { break; case KEY_LEFT: clear(); - g_page = (g_page - 1) % PAGE_COUNT; + g_page = (g_page + PAGE_COUNT - 1) % PAGE_COUNT; break; case KEY_RIGHT: clear(); @@ -1134,6 +1297,9 @@ void ev_handle() { } } +// ---------------------------------------------------------------------------- +// Main functions +// ---------------------------------------------------------------------------- void init() { setlocale(LC_ALL, ""); @@ -1148,6 +1314,7 @@ void init() { init_pair(PAIR_NORMAL, COLOR_WHITE, COLOR_BLACK ); init_pair(PAIR_HEADER, COLOR_BLUE, COLOR_BLACK ); + init_pair(PAIR_WARN, COLOR_RED, COLOR_BLACK ); init_pair(PAIR_LIVE_PROC, COLOR_BLUE, COLOR_BLACK ); init_pair(PAIR_SELECTED_PROC, COLOR_YELLOW, COLOR_BLACK ); init_pair(PAIR_FREE_CELL, COLOR_BLACK, COLOR_BLUE ); @@ -1158,6 +1325,10 @@ void init() { init_pair(PAIR_SELECTED_IP, COLOR_BLACK, COLOR_RED ); init_pair(PAIR_SELECTED_SP, COLOR_BLACK, COLOR_MAGENTA); + // Install loggers + g_info = ui_info_impl; + g_warn = ui_warn_impl; + {% if args.command == "new" %} salis_init(); {% elif args.command == "load" %} diff --git a/ui/daemon/ui.j2.c b/ui/daemon/ui.j2.c index 7d92f9d..02df79b 100644 --- a/ui/daemon/ui.j2.c +++ b/ui/daemon/ui.j2.c @@ -8,13 +8,36 @@ volatile bool g_running; uint64_t g_step_block; +void info_impl(const char *restrict fmt, ...) { + assert(fmt); + printf("\033[1;34mINFO:\033[0m "); + + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + printf("\n"); +} + +void warn_impl(const char *restrict fmt, ...) { + assert(fmt); + printf("\033[1;31mWARN:\033[0m "); + + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + printf("\n"); +} + void sig_handler(int signo) { - switch (signo) { - case SIGINT: - case SIGTERM: - printf("Signal received, will stop simulator soon...\n"); + (void)signo; + + if (g_running) { + g_warn("Signal received, will stop simulator soon..."); g_running = false; - break; } } @@ -31,10 +54,13 @@ void step_block() { g_step_block >>= 1; } - printf("Simulator running on step '%#lx'\n", g_steps); + g_info("Simulator running on step '%#lx'", g_steps); } int main() { + g_info = info_impl; + g_warn = warn_impl; + {% if args.command == "new" %} salis_init(); {% elif args.command == "load" %} @@ -51,10 +77,10 @@ int main() { step_block(); } - printf("Saving simulation...\n"); + g_info("Saving simulation..."); salis_save("{{ sim_path }}"); salis_free(); - printf("Exiting salis...\n"); + g_info("Exiting salis..."); return 0; } |
