completely redesign how user mode memory is allocated, fix a few smp and scheduler bugs, terminating a process now terminates the process, telemetry, optimize text editor, new font, new color scheme

This commit is contained in:
maksw committed 2026-06-09 18:02:28 +02:00
1 parent 27b31f62b6
commit 325149006c
45 files changed
+2091 -760

No files matched your search

+5 -4
View File
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <intrin.h>
@@ -28,7 +29,7 @@ static void doom_print_wrapper(const char* msg)
// ---------------------------------------------------------------------------
static void* doom_malloc_wrapper(int size)
{
void* p = SysAlloc(size);
void* p = malloc(size);
if (!p) SysExitProcess(1);
return p;
}
@@ -37,7 +38,7 @@ static void doom_free_wrapper(void* ptr)
{
if (!ptr) return;
SysFree(ptr);
free(ptr);
}
// ---------------------------------------------------------------------------
@@ -62,7 +63,7 @@ static void* doom_open_wrapper(const char* path, const char* mode)
}
if (result != 0) return 0;
DOOM_FILE_HANDLE* f = (DOOM_FILE_HANDLE*)SysAlloc(sizeof(DOOM_FILE_HANDLE));
DOOM_FILE_HANDLE* f = (DOOM_FILE_HANDLE*)malloc(sizeof(DOOM_FILE_HANDLE));
if (!f) {
SysCloseHandle(handle);
return 0;
@@ -79,7 +80,7 @@ static void doom_close_wrapper(void* handle)
if (!handle) return;
DOOM_FILE_HANDLE* f = (DOOM_FILE_HANDLE*)handle;
SysCloseHandle(f->Handle);
SysFree(f);
free(f);
}
static int doom_read_wrapper(void* handle, void* buf, int count)
+75 -18
View File
@@ -18,6 +18,8 @@
#define MAX_LINE 256
#define PATH_MAX2 260
#define MSG_MAX 160
#define MAX_SCREEN_COLS 256
#define MAX_SCREEN_ROWS 128
#define COL_BG 0x000000u
#define COL_FG 0xC8C8C8u
@@ -61,8 +63,55 @@ static bool gQuitArmed = false;
static char gFilename[PATH_MAX2] = "untitled.txt";
static char gMessage[MSG_MAX] = "ready";
typedef struct SCREEN_CELL {
char c;
uint32_t fg;
uint32_t bg;
} SCREEN_CELL;
static SCREEN_CELL gScreenCache[MAX_SCREEN_COLS * MAX_SCREEN_ROWS];
static bool gScreenCacheValid = false;
static void invalidate_screen_cache(void) {
gScreenCacheValid = false;
}
static void update_screen_size(void) {
int pxW = 0, pxH = 0;
int oldCols = gCols;
int oldRows = gRows;
if (SysScreenGetSize(&pxW, &pxH) == 0 && pxW > 0 && pxH > 0) {
gCols = pxW / GLYPH_W;
gRows = pxH / GLYPH_H;
if (gCols < 20) gCols = 20;
if (gRows < 5) gRows = 5;
if (gCols > MAX_SCREEN_COLS) gCols = MAX_SCREEN_COLS;
if (gRows > MAX_SCREEN_ROWS) gRows = MAX_SCREEN_ROWS;
}
if (gCols != oldCols || gRows != oldRows)
invalidate_screen_cache();
}
static void put_cell(int col, int row, char c, uint32_t fg, uint32_t bg) {
SysScreenPutChar(c ? c : ' ', col * GLYPH_W, row * GLYPH_H, fg, bg);
if (col < 0 || row < 0 || col >= gCols || row >= gRows)
return;
if (!c) c = ' ';
if (col < MAX_SCREEN_COLS && row < MAX_SCREEN_ROWS) {
SCREEN_CELL* cell = &gScreenCache[row * MAX_SCREEN_COLS + col];
if (gScreenCacheValid && cell->c == c && cell->fg == fg && cell->bg == bg)
return;
cell->c = c;
cell->fg = fg;
cell->bg = bg;
}
SysScreenPutChar(c, col * GLYPH_W, row * GLYPH_H, fg, bg);
}
static void clear_row(int row, uint32_t bg) {
@@ -151,13 +200,7 @@ static void ensure_visible(void) {
}
static void render(void) {
int pxW = 0, pxH = 0;
if (SysScreenGetSize(&pxW, &pxH) == 0 && pxW > 0 && pxH > 0) {
gCols = pxW / GLYPH_W;
gRows = pxH / GLYPH_H;
if (gCols < 20) gCols = 20;
if (gRows < 5) gRows = 5;
}
update_screen_size();
clamp_cursor();
ensure_visible();
@@ -172,28 +215,40 @@ static void render(void) {
append_str(status, sizeof(status), &p, ", Col ");
append_u32(status, sizeof(status), &p, (uint32_t)(gCx + 1));
clear_row(0, COL_STATUS);
draw_text(0, 0, status, COL_STATUSF, COL_STATUS);
size_t statusLen = p;
for (int sx = 0; sx < gCols; sx++) {
char c = ((size_t)sx < statusLen) ? status[sx] : ' ';
put_cell(sx, 0, c, COL_STATUSF, COL_STATUS);
}
int textRows = gRows - 2;
for (int sy = 0; sy < textRows; sy++) {
int row = sy + 1;
int li = gTop + sy;
clear_row(row, COL_BG);
if (li >= gLineCount) continue;
LINE* ln = &gLines[li];
for (int sx = 0; sx < gCols; sx++) {
int ci = gLeft + sx;
char c = (ci < ln->len) ? ln->text[ci] : ' ';
bool atCursor = (li == gCy && ci == gCx);
char c = ' ';
bool atCursor = false;
if (li < gLineCount) {
LINE* ln = &gLines[li];
c = (ci < ln->len) ? ln->text[ci] : ' ';
atCursor = (li == gCy && ci == gCx);
}
put_cell(sx, row, c, atCursor ? COL_CURSORF : COL_FG,
atCursor ? COL_CURSOR : COL_BG);
}
}
clear_row(gRows - 1, COL_STATUS);
draw_text(0, gRows - 1, gMessage, COL_STATUSF, COL_STATUS);
size_t messageLen = strlen(gMessage);
for (int sx = 0; sx < gCols; sx++) {
char c = ((size_t)sx < messageLen) ? gMessage[sx] : ' ';
put_cell(sx, gRows - 1, c, COL_STATUSF, COL_STATUS);
}
gScreenCacheValid = true;
}
static void insert_char_at_cursor(char c) {
@@ -481,8 +536,10 @@ int main(void) {
parse_filename_from_cmdline();
load_file();
SysScreenClear(COL_BG);
invalidate_screen_cache();
editor_loop();
SysScreenClear(COL_BG);
SysScreenClear(0x012456);
invalidate_screen_cache();
print("edit: goodbye\n");
SysExitProcess(0);
return 0;
+93 -1
View File
@@ -95,6 +95,7 @@ static void cmd_help() {
print("Available commands:\n"
" help - Show this list\n"
" mem - Show memory usage\n"
" stats - Show scheduler/CPU/PMM telemetry\n"
" ps - List running process IDs\n"
" dir [path] - List directory contents\n"
" cd <path> - Change directory\n"
@@ -110,6 +111,96 @@ static void printSizeKiB(uint64_t bytes) {
print(" KiB");
}
static void printPagesKiB(uint64_t pages) {
printUInt64(pages * 4u);
print(" KiB");
}
static void printCpuFlags(uint32_t flags) {
if (flags & SYS_CPU_FLAG_BSP) print("bsp ");
if (flags & SYS_CPU_FLAG_ONLINE) print("online ");
if (flags & SYS_CPU_FLAG_PARKED) print("parked ");
if (flags & SYS_CPU_FLAG_PRIMARY) print("primary ");
if (flags & SYS_CPU_FLAG_STARTED) print("started ");
if (flags & SYS_CPU_FLAG_PRESENT) print("present ");
}
static void cmd_stats(void) {
SYS_SCHEDULER_STATS sched;
SYS_PMM_STATS pmm;
SYS_CPU_STATS cpu;
uint32_t status;
status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, &sched, sizeof(sched), NULL);
if (status != 0) {
print("stats: scheduler query failed: ");
printUInt(status);
print("\n");
return;
}
status = SysQueryKernelStats(SYS_KERNEL_STATS_PMM, &pmm, sizeof(pmm), NULL);
if (status != 0) {
print("stats: pmm query failed: ");
printUInt(status);
print("\n");
return;
}
status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, &cpu, sizeof(cpu), NULL);
if (status != 0) {
print("stats: cpu query failed: ");
printUInt(status);
print("\n");
return;
}
print("Scheduler:\n");
print(" ticks: "); printUInt64(sched.Ticks); print("\n");
print(" context switches: "); printUInt64(sched.ContextSwitches); print("\n");
print(" quantum expires: "); printUInt64(sched.QuantumExpirations); print("\n");
print(" priority preempts: "); printUInt64(sched.PriorityPreemptions); print("\n");
print(" idle selections: "); printUInt64(sched.IdleSelections); print("\n");
print(" keep-current: "); printUInt64(sched.KeepCurrentDecisions); print("\n");
print(" demotions: "); printUInt64(sched.Demotions); print("\n");
print(" aging promotions: "); printUInt64(sched.AgingPromotions); print("\n");
print(" voluntary blocks: "); printUInt64(sched.VoluntaryBlocks); print("\n");
print(" SMT deferrals: "); printUInt64(sched.SmtSiblingDeferrals); print("\n");
print(" SMT primary pokes: "); printUInt64(sched.SmtPrimaryPokes); print("\n");
print("CPUs:\n");
uint32_t n = cpu.CpuCount;
if (n > SYS_KERNEL_STATS_MAX_CPUS)
n = SYS_KERNEL_STATS_MAX_CPUS;
for (uint32_t i = 0; i < n; i++) {
SYS_CPU_STAT* c = &cpu.Cpu[i];
print(" cpu"); printUInt(c->CpuIndex);
print(" lapic="); printUInt(c->LapicId);
print(" tid="); printUInt(c->CurrentTid);
print(" ticks="); printUInt64(c->SchedulerTicks);
print(" switches="); printUInt64(c->ContextSwitches);
print(" flags="); printCpuFlags(c->Flags);
print("\n");
}
print("Physical memory:\n");
print(" total: "); printPagesKiB(pmm.TotalFrames); print(" (frames="); printUInt64(pmm.TotalFrames); print(")\n");
print(" used: "); printPagesKiB(pmm.UsedFrames); print(" (frames="); printUInt64(pmm.UsedFrames); print(")\n");
print(" free: "); printPagesKiB(pmm.FreeFrames); print(" (frames="); printUInt64(pmm.FreeFrames); print(")\n");
print(" largest free run: "); printPagesKiB(pmm.LargestFreeRun); print(" (frames="); printUInt64(pmm.LargestFreeRun); print(")\n");
print(" free runs: "); printUInt64(pmm.FreeRunCount); print("\n");
print(" run histogram:\n");
print(" 1: "); printUInt64(pmm.FreeRunHistogram[0]); print("\n");
print(" 2-3: "); printUInt64(pmm.FreeRunHistogram[1]); print("\n");
print(" 4-7: "); printUInt64(pmm.FreeRunHistogram[2]); print("\n");
print(" 8-15: "); printUInt64(pmm.FreeRunHistogram[3]); print("\n");
print(" 16-63: "); printUInt64(pmm.FreeRunHistogram[4]); print("\n");
print(" 64-255: "); printUInt64(pmm.FreeRunHistogram[5]); print("\n");
print(" 256-1023: "); printUInt64(pmm.FreeRunHistogram[6]); print("\n");
print(" 1024+: "); printUInt64(pmm.FreeRunHistogram[7]); print("\n");
}
static void cmd_mem(void) {
SYS_MEMORY_STATUS st;
if (SysGetMemoryStatus(&st) != 0) {
@@ -240,7 +331,7 @@ static int runCommand(const char* cmd) {
if (!cmd || *cmd == '\0') return 0;
if (strcmp(cmd, "exit") == 0) return 1;
if (strcmp(cmd, "help") == 0) { cmd_help(); return 0; }
if (strcmp(cmd, "clear") == 0) { SysScreenClear(0); return 0; }
if (strcmp(cmd, "clear") == 0) { SysScreenClear(0x012456); return 0; }
if (strncmp(cmd, "crash", 5) == 0) {
// Check the sub-option trailing "crash " (offset 6)
if (strcmp(cmd + 6, "void") == 0) {
@@ -280,6 +371,7 @@ static int runCommand(const char* cmd) {
}
}
if (strcmp(cmd, "mem") == 0) { cmd_mem(); return 0; }
if (strcmp(cmd, "stats") == 0 || strcmp(cmd, "telemetry") == 0) { cmd_stats(); return 0; }
if (strcmp(cmd, "ps") == 0) { cmd_ps(); return 0; }
if (strcmp(cmd, "dir") == 0) { cmd_dir("."); return 0; }
if (strncmp(cmd, "dir ", 4) == 0) { cmd_dir(cmd + 4); return 0; }