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:
1 parent
27b31f62b6
commit
325149006c
45 files changed
+2091
-760
No files matched your search
@@ -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
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in new issue
Block a user