mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
更好的进程系统
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user