更好的进程系统

This commit is contained in:
2026-04-17 17:07:19 +08:00
parent bf41872d8d
commit f93af4a2a6
17 changed files with 1385 additions and 35 deletions

View File

@@ -3,6 +3,30 @@
#include <clks/types.h>
#define CLKS_EXEC_PROC_PATH_MAX 192U
#define CLKS_EXEC_PROC_STATE_UNUSED 0ULL
#define CLKS_EXEC_PROC_STATE_PENDING 1ULL
#define CLKS_EXEC_PROC_STATE_RUNNING 2ULL
#define CLKS_EXEC_PROC_STATE_EXITED 3ULL
struct clks_exec_proc_snapshot {
u64 pid;
u64 ppid;
u64 state;
u64 started_tick;
u64 exited_tick;
u64 exit_status;
u64 runtime_ticks;
u64 mem_bytes;
u64 tty_index;
u64 last_signal;
u64 last_fault_vector;
u64 last_fault_error;
u64 last_fault_rip;
char path[CLKS_EXEC_PROC_PATH_MAX];
};
void clks_exec_init(void);
clks_bool clks_exec_run_path(const char *path, u64 *out_status);
clks_bool clks_exec_run_pathv(const char *path, const char *argv_line, const char *env_line, u64 *out_status);
@@ -20,6 +44,10 @@ u64 clks_exec_current_signal(void);
u64 clks_exec_current_fault_vector(void);
u64 clks_exec_current_fault_error(void);
u64 clks_exec_current_fault_rip(void);
u64 clks_exec_proc_count(void);
clks_bool clks_exec_proc_pid_at(u64 index, u64 *out_pid);
clks_bool clks_exec_proc_snapshot(u64 pid, struct clks_exec_proc_snapshot *out_snapshot);
u64 clks_exec_proc_kill(u64 pid, u64 signal);
clks_bool clks_exec_handle_exception(u64 vector,
u64 error_code,
u64 rip,

View File

@@ -64,6 +64,10 @@
#define CLKS_SYSCALL_PROC_FAULT_VECTOR 58ULL
#define CLKS_SYSCALL_PROC_FAULT_ERROR 59ULL
#define CLKS_SYSCALL_PROC_FAULT_RIP 60ULL
#define CLKS_SYSCALL_PROC_COUNT 61ULL
#define CLKS_SYSCALL_PROC_PID_AT 62ULL
#define CLKS_SYSCALL_PROC_SNAPSHOT 63ULL
#define CLKS_SYSCALL_PROC_KILL 64ULL
void clks_syscall_init(void);
u64 clks_syscall_dispatch(void *frame_ptr);

View File

@@ -22,6 +22,7 @@ typedef u64 (*clks_exec_entry_fn)(void);
#define CLKS_EXEC_MAX_ENVS 24U
#define CLKS_EXEC_ITEM_MAX 128U
#define CLKS_EXEC_STATUS_SIGNAL_FLAG (1ULL << 63)
#define CLKS_EXEC_DEFAULT_KILL_SIGNAL 15ULL
enum clks_exec_proc_state {
CLKS_EXEC_PROC_UNUSED = 0,
@@ -39,6 +40,7 @@ struct clks_exec_proc_record {
u64 exited_tick;
u64 exit_status;
u32 tty_index;
u64 image_mem_bytes;
char path[CLKS_EXEC_PATH_MAX];
char argv_line[CLKS_EXEC_ARG_LINE_MAX];
char env_line[CLKS_EXEC_ENV_LINE_MAX];
@@ -413,6 +415,7 @@ static struct clks_exec_proc_record *clks_exec_prepare_proc_record(i32 slot,
proc->exited_tick = 0ULL;
proc->exit_status = (u64)-1;
proc->tty_index = clks_tty_active();
proc->image_mem_bytes = 0ULL;
clks_exec_copy_path(proc->path, sizeof(proc->path), path);
clks_exec_copy_line(proc->argv_line, sizeof(proc->argv_line), argv_line);
clks_exec_copy_line(proc->env_line, sizeof(proc->env_line), env_line);
@@ -544,6 +547,8 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
goto fail;
}
proc->image_mem_bytes = info.total_load_memsz;
if (clks_elf64_load(image, image_size, &loaded) == CLKS_FALSE) {
clks_log(CLKS_LOG_WARN, "EXEC", "EXEC ELF LOAD FAILED");
clks_log(CLKS_LOG_WARN, "EXEC", proc->path);
@@ -958,6 +963,190 @@ u64 clks_exec_current_fault_rip(void) {
return (proc != CLKS_NULL) ? proc->last_fault_rip : 0ULL;
}
static u64 clks_exec_proc_runtime_ticks(const struct clks_exec_proc_record *proc, u64 now_tick) {
if (proc == CLKS_NULL || proc->started_tick == 0ULL) {
return 0ULL;
}
if (proc->state == CLKS_EXEC_PROC_RUNNING) {
if (now_tick <= proc->started_tick) {
return 0ULL;
}
return now_tick - proc->started_tick;
}
if (proc->state == CLKS_EXEC_PROC_EXITED) {
if (proc->exited_tick <= proc->started_tick) {
return 0ULL;
}
return proc->exited_tick - proc->started_tick;
}
return 0ULL;
}
static u64 clks_exec_proc_memory_bytes(const struct clks_exec_proc_record *proc) {
u64 mem = 0ULL;
if (proc == CLKS_NULL) {
return 0ULL;
}
mem += proc->image_mem_bytes;
if (proc->state == CLKS_EXEC_PROC_RUNNING) {
mem += CLKS_EXEC_RUN_STACK_BYTES;
}
return mem;
}
u64 clks_exec_proc_count(void) {
u64 count = 0ULL;
u32 i;
for (i = 0U; i < CLKS_EXEC_MAX_PROCS; i++) {
if (clks_exec_proc_table[i].used == CLKS_TRUE) {
count++;
}
}
return count;
}
clks_bool clks_exec_proc_pid_at(u64 index, u64 *out_pid) {
u64 pos = 0ULL;
u32 i;
if (out_pid != CLKS_NULL) {
*out_pid = 0ULL;
}
if (out_pid == CLKS_NULL) {
return CLKS_FALSE;
}
for (i = 0U; i < CLKS_EXEC_MAX_PROCS; i++) {
if (clks_exec_proc_table[i].used != CLKS_TRUE) {
continue;
}
if (pos == index) {
*out_pid = clks_exec_proc_table[i].pid;
return CLKS_TRUE;
}
pos++;
}
return CLKS_FALSE;
}
clks_bool clks_exec_proc_snapshot(u64 pid, struct clks_exec_proc_snapshot *out_snapshot) {
i32 slot;
const struct clks_exec_proc_record *proc;
u64 now_tick;
if (out_snapshot == CLKS_NULL) {
return CLKS_FALSE;
}
slot = clks_exec_proc_find_slot_by_pid(pid);
if (slot < 0) {
return CLKS_FALSE;
}
proc = &clks_exec_proc_table[(u32)slot];
if (proc->used != CLKS_TRUE) {
return CLKS_FALSE;
}
now_tick = clks_interrupts_timer_ticks();
clks_memset(out_snapshot, 0, sizeof(*out_snapshot));
out_snapshot->pid = proc->pid;
out_snapshot->ppid = proc->ppid;
out_snapshot->state = (u64)proc->state;
out_snapshot->started_tick = proc->started_tick;
out_snapshot->exited_tick = proc->exited_tick;
out_snapshot->exit_status = proc->exit_status;
out_snapshot->runtime_ticks = clks_exec_proc_runtime_ticks(proc, now_tick);
out_snapshot->mem_bytes = clks_exec_proc_memory_bytes(proc);
out_snapshot->tty_index = (u64)proc->tty_index;
out_snapshot->last_signal = proc->last_signal;
out_snapshot->last_fault_vector = proc->last_fault_vector;
out_snapshot->last_fault_error = proc->last_fault_error;
out_snapshot->last_fault_rip = proc->last_fault_rip;
clks_exec_copy_path(out_snapshot->path, sizeof(out_snapshot->path), proc->path);
return CLKS_TRUE;
}
u64 clks_exec_proc_kill(u64 pid, u64 signal) {
i32 slot;
struct clks_exec_proc_record *proc;
u64 effective_signal;
u64 status;
u64 now_tick;
if (pid == 0ULL) {
return (u64)-1;
}
slot = clks_exec_proc_find_slot_by_pid(pid);
if (slot < 0) {
return (u64)-1;
}
proc = &clks_exec_proc_table[(u32)slot];
if (proc->used != CLKS_TRUE) {
return (u64)-1;
}
effective_signal = (signal == 0ULL) ? CLKS_EXEC_DEFAULT_KILL_SIGNAL : (signal & 0xFFULL);
status = clks_exec_encode_signal_status(effective_signal, 0ULL, 0ULL);
now_tick = clks_interrupts_timer_ticks();
if (proc->state == CLKS_EXEC_PROC_EXITED) {
return 1ULL;
}
if (proc->state == CLKS_EXEC_PROC_PENDING) {
proc->state = CLKS_EXEC_PROC_EXITED;
proc->exit_status = status;
proc->exited_tick = now_tick;
proc->last_signal = effective_signal;
proc->last_fault_vector = 0ULL;
proc->last_fault_error = 0ULL;
proc->last_fault_rip = 0ULL;
return 1ULL;
}
if (proc->state == CLKS_EXEC_PROC_RUNNING) {
i32 depth_index = clks_exec_current_depth_index();
if (depth_index < 0 || clks_exec_current_pid() != pid) {
return 0ULL;
}
proc->last_signal = effective_signal;
proc->last_fault_vector = 0ULL;
proc->last_fault_error = 0ULL;
proc->last_fault_rip = 0ULL;
clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_TRUE;
clks_exec_exit_status_stack[(u32)depth_index] = status;
return 1ULL;
}
return 0ULL;
}
clks_bool clks_exec_handle_exception(u64 vector,
u64 error_code,
u64 rip,

View File

@@ -6,6 +6,8 @@
#define CLKS_LOG_LINE_MAX 256
#define CLKS_LOG_JOURNAL_CAP 256
#define CLKS_LOG_ANSI_RESET "\x1B[0m"
static char clks_log_journal[CLKS_LOG_JOURNAL_CAP][CLKS_LOG_LINE_MAX];
static u32 clks_log_journal_head = 0U;
static u32 clks_log_journal_count_live = 0U;
@@ -37,6 +39,10 @@ static void clks_log_append_char(char *buffer, usize *cursor, char ch) {
static void clks_log_append_text(char *buffer, usize *cursor, const char *text) {
usize i = 0;
if (text == CLKS_NULL) {
return;
}
while (text[i] != '\0') {
clks_log_append_char(buffer, cursor, text[i]);
i++;
@@ -83,51 +89,121 @@ static void clks_log_journal_push(const char *line) {
}
}
static void clks_log_emit_line(const char *line) {
static const char *clks_log_level_ansi(enum clks_log_level level) {
switch (level) {
case CLKS_LOG_DEBUG:
return "\x1B[38;5;110m";
case CLKS_LOG_INFO:
return "\x1B[38;5;120m";
case CLKS_LOG_WARN:
return "\x1B[1;38;5;220m";
case CLKS_LOG_ERROR:
return "\x1B[1;38;5;203m";
default:
return "\x1B[38;5;250m";
}
}
static const char *clks_log_tag_ansi(const char *tag) {
static const char *palette[] = {
"\x1B[38;5;81m",
"\x1B[38;5;117m",
"\x1B[38;5;159m",
"\x1B[38;5;45m",
"\x1B[38;5;75m",
"\x1B[38;5;141m",
"\x1B[38;5;214m",
"\x1B[38;5;168m",
};
u32 hash = 5381U;
usize i = 0U;
usize palette_count = sizeof(palette) / sizeof(palette[0]);
if (tag == CLKS_NULL || tag[0] == '\0') {
return palette[0];
}
while (tag[i] != '\0') {
hash = ((hash << 5U) + hash) ^ (u32)(u8)tag[i];
i++;
}
return palette[hash % (u32)palette_count];
}
static void clks_log_emit_tty_colored(enum clks_log_level level, const char *tag, const char *message) {
const char *safe_tag = (tag == CLKS_NULL) ? "LOG" : tag;
const char *safe_message = (message == CLKS_NULL) ? "" : message;
clks_tty_write(clks_log_level_ansi(level));
clks_tty_write("[");
clks_tty_write(clks_log_level_name(level));
clks_tty_write("]");
clks_tty_write(clks_log_tag_ansi(safe_tag));
clks_tty_write("[");
clks_tty_write(safe_tag);
clks_tty_write("]");
clks_tty_write(CLKS_LOG_ANSI_RESET);
clks_tty_write(" ");
clks_tty_write(safe_message);
clks_tty_write("\n");
}
static void clks_log_build_line(enum clks_log_level level, const char *tag, const char *message, char *line) {
const char *safe_tag = (tag == CLKS_NULL) ? "LOG" : tag;
const char *safe_message = (message == CLKS_NULL) ? "" : message;
usize cursor = 0U;
if (line == CLKS_NULL) {
return;
}
clks_log_append_char(line, &cursor, '[');
clks_log_append_text(line, &cursor, clks_log_level_name(level));
clks_log_append_char(line, &cursor, ']');
clks_log_append_char(line, &cursor, '[');
clks_log_append_text(line, &cursor, safe_tag);
clks_log_append_char(line, &cursor, ']');
clks_log_append_char(line, &cursor, ' ');
clks_log_append_text(line, &cursor, safe_message);
line[cursor] = '\0';
}
static void clks_log_emit_line(enum clks_log_level level, const char *tag, const char *message, const char *line) {
if (line == CLKS_NULL) {
return;
}
clks_log_journal_push(line);
clks_serial_write(line);
clks_serial_write("\n");
clks_tty_write(line);
clks_tty_write("\n");
clks_log_emit_tty_colored(level, tag, message);
}
void clks_log(enum clks_log_level level, const char *tag, const char *message) {
char line[CLKS_LOG_LINE_MAX];
usize cursor = 0;
clks_log_append_char(line, &cursor, '[');
clks_log_append_text(line, &cursor, clks_log_level_name(level));
clks_log_append_char(line, &cursor, ']');
clks_log_append_char(line, &cursor, '[');
clks_log_append_text(line, &cursor, tag);
clks_log_append_char(line, &cursor, ']');
clks_log_append_char(line, &cursor, ' ');
clks_log_append_text(line, &cursor, message);
line[cursor] = '\0';
clks_log_emit_line(line);
clks_log_build_line(level, tag, message, line);
clks_log_emit_line(level, tag, message, line);
}
void clks_log_hex(enum clks_log_level level, const char *tag, const char *label, u64 value) {
char message[CLKS_LOG_LINE_MAX];
char line[CLKS_LOG_LINE_MAX];
usize cursor = 0;
usize cursor = 0U;
clks_log_append_char(line, &cursor, '[');
clks_log_append_text(line, &cursor, clks_log_level_name(level));
clks_log_append_char(line, &cursor, ']');
clks_log_append_char(line, &cursor, '[');
clks_log_append_text(line, &cursor, tag);
clks_log_append_char(line, &cursor, ']');
clks_log_append_char(line, &cursor, ' ');
clks_log_append_text(line, &cursor, label);
clks_log_append_char(line, &cursor, ':');
clks_log_append_char(line, &cursor, ' ');
clks_log_append_hex_u64(line, &cursor, value);
line[cursor] = '\0';
clks_log_append_text(message, &cursor, (label == CLKS_NULL) ? "VALUE" : label);
clks_log_append_char(message, &cursor, ':');
clks_log_append_char(message, &cursor, ' ');
clks_log_append_hex_u64(message, &cursor, value);
message[cursor] = '\0';
clks_log_emit_line(line);
clks_log_build_line(level, tag, message, line);
clks_log_emit_line(level, tag, message, line);
}
u64 clks_log_journal_count(void) {
@@ -153,4 +229,4 @@ clks_bool clks_log_journal_read(u64 index_from_oldest, char *out_line, usize out
clks_log_journal_copy_line(out_line, out_line_size, clks_log_journal[slot]);
return CLKS_TRUE;
}
}

View File

@@ -362,6 +362,44 @@ static u64 clks_syscall_proc_fault_rip(void) {
return clks_exec_current_fault_rip();
}
static u64 clks_syscall_proc_count(void) {
return clks_exec_proc_count();
}
static u64 clks_syscall_proc_pid_at(u64 arg0, u64 arg1) {
u64 pid = 0ULL;
if (arg1 == 0ULL) {
return 0ULL;
}
if (clks_exec_proc_pid_at(arg0, &pid) == CLKS_FALSE) {
return 0ULL;
}
clks_memcpy((void *)arg1, &pid, sizeof(pid));
return 1ULL;
}
static u64 clks_syscall_proc_snapshot(u64 arg0, u64 arg1, u64 arg2) {
struct clks_exec_proc_snapshot snap;
if (arg1 == 0ULL || arg2 < (u64)sizeof(snap)) {
return 0ULL;
}
if (clks_exec_proc_snapshot(arg0, &snap) == CLKS_FALSE) {
return 0ULL;
}
clks_memcpy((void *)arg1, &snap, sizeof(snap));
return 1ULL;
}
static u64 clks_syscall_proc_kill(u64 arg0, u64 arg1) {
return clks_exec_proc_kill(arg0, arg1);
}
static u64 clks_syscall_exit(u64 arg0) {
return (clks_exec_request_exit(arg0) == CLKS_TRUE) ? 1ULL : 0ULL;
}
@@ -723,6 +761,14 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
return clks_syscall_proc_fault_error();
case CLKS_SYSCALL_PROC_FAULT_RIP:
return clks_syscall_proc_fault_rip();
case CLKS_SYSCALL_PROC_COUNT:
return clks_syscall_proc_count();
case CLKS_SYSCALL_PROC_PID_AT:
return clks_syscall_proc_pid_at(frame->rbx, frame->rcx);
case CLKS_SYSCALL_PROC_SNAPSHOT:
return clks_syscall_proc_snapshot(frame->rbx, frame->rcx, frame->rdx);
case CLKS_SYSCALL_PROC_KILL:
return clks_syscall_proc_kill(frame->rbx, frame->rcx);
case CLKS_SYSCALL_EXIT:
return clks_syscall_exit(frame->rbx);
case CLKS_SYSCALL_SLEEP_TICKS: