mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
Stage 29B
This commit is contained in:
@@ -9,6 +9,7 @@ clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid);
|
|||||||
u64 clks_exec_wait_pid(u64 pid, u64 *out_status);
|
u64 clks_exec_wait_pid(u64 pid, u64 *out_status);
|
||||||
clks_bool clks_exec_request_exit(u64 status);
|
clks_bool clks_exec_request_exit(u64 status);
|
||||||
u64 clks_exec_current_pid(void);
|
u64 clks_exec_current_pid(void);
|
||||||
|
u32 clks_exec_current_tty(void);
|
||||||
u64 clks_exec_sleep_ticks(u64 ticks);
|
u64 clks_exec_sleep_ticks(u64 ticks);
|
||||||
u64 clks_exec_yield(void);
|
u64 clks_exec_yield(void);
|
||||||
void clks_exec_tick(u64 tick);
|
void clks_exec_tick(u64 tick);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ void clks_keyboard_init(void);
|
|||||||
void clks_keyboard_handle_scancode(u8 scancode);
|
void clks_keyboard_handle_scancode(u8 scancode);
|
||||||
u64 clks_keyboard_hotkey_switch_count(void);
|
u64 clks_keyboard_hotkey_switch_count(void);
|
||||||
clks_bool clks_keyboard_pop_char(char *out_ch);
|
clks_bool clks_keyboard_pop_char(char *out_ch);
|
||||||
|
clks_bool clks_keyboard_pop_char_for_tty(u32 tty_index, char *out_ch);
|
||||||
u64 clks_keyboard_buffered_count(void);
|
u64 clks_keyboard_buffered_count(void);
|
||||||
u64 clks_keyboard_drop_count(void);
|
u64 clks_keyboard_drop_count(void);
|
||||||
u64 clks_keyboard_push_count(void);
|
u64 clks_keyboard_push_count(void);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <clks/log.h>
|
#include <clks/log.h>
|
||||||
#include <clks/string.h>
|
#include <clks/string.h>
|
||||||
#include <clks/types.h>
|
#include <clks/types.h>
|
||||||
|
#include <clks/tty.h>
|
||||||
|
|
||||||
typedef u64 (*clks_exec_entry_fn)(void);
|
typedef u64 (*clks_exec_entry_fn)(void);
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ struct clks_exec_proc_record {
|
|||||||
u64 started_tick;
|
u64 started_tick;
|
||||||
u64 exited_tick;
|
u64 exited_tick;
|
||||||
u64 exit_status;
|
u64 exit_status;
|
||||||
|
u32 tty_index;
|
||||||
char path[CLKS_EXEC_PATH_MAX];
|
char path[CLKS_EXEC_PATH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -206,6 +208,7 @@ static struct clks_exec_proc_record *clks_exec_prepare_proc_record(i32 slot,
|
|||||||
proc->started_tick = 0ULL;
|
proc->started_tick = 0ULL;
|
||||||
proc->exited_tick = 0ULL;
|
proc->exited_tick = 0ULL;
|
||||||
proc->exit_status = (u64)-1;
|
proc->exit_status = (u64)-1;
|
||||||
|
proc->tty_index = clks_tty_active();
|
||||||
clks_exec_copy_path(proc->path, sizeof(proc->path), path);
|
clks_exec_copy_path(proc->path, sizeof(proc->path), path);
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
@@ -583,6 +586,36 @@ u64 clks_exec_current_pid(void) {
|
|||||||
return clks_exec_pid_stack[(u32)depth_index];
|
return clks_exec_pid_stack[(u32)depth_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 clks_exec_current_tty(void) {
|
||||||
|
i32 depth_index = clks_exec_current_depth_index();
|
||||||
|
u32 tty_count = clks_tty_count();
|
||||||
|
i32 slot;
|
||||||
|
const struct clks_exec_proc_record *proc;
|
||||||
|
|
||||||
|
if (tty_count == 0U) {
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth_index < 0) {
|
||||||
|
u32 active = clks_tty_active();
|
||||||
|
return (active < tty_count) ? active : 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
slot = clks_exec_proc_find_slot_by_pid(clks_exec_pid_stack[(u32)depth_index]);
|
||||||
|
|
||||||
|
if (slot < 0) {
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc = &clks_exec_proc_table[(u32)slot];
|
||||||
|
|
||||||
|
if (proc->used == CLKS_FALSE || proc->tty_index >= tty_count) {
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
return proc->tty_index;
|
||||||
|
}
|
||||||
|
|
||||||
u64 clks_exec_sleep_ticks(u64 ticks) {
|
u64 clks_exec_sleep_ticks(u64 ticks) {
|
||||||
u64 start = clks_interrupts_timer_ticks();
|
u64 start = clks_interrupts_timer_ticks();
|
||||||
|
|
||||||
@@ -649,4 +682,4 @@ clks_bool clks_exec_current_path_is_user(void) {
|
|||||||
|
|
||||||
proc = &clks_exec_proc_table[(u32)slot];
|
proc = &clks_exec_proc_table[(u32)slot];
|
||||||
return clks_exec_path_is_user_program(proc->path);
|
return clks_exec_path_is_user_program(proc->path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#define CLKS_SC_EXT_DELETE 0x53U
|
#define CLKS_SC_EXT_DELETE 0x53U
|
||||||
|
|
||||||
#define CLKS_KBD_INPUT_CAP 256U
|
#define CLKS_KBD_INPUT_CAP 256U
|
||||||
|
#define CLKS_KBD_TTY_MAX 8U
|
||||||
#define CLKS_KBD_DROP_LOG_EVERY 64ULL
|
#define CLKS_KBD_DROP_LOG_EVERY 64ULL
|
||||||
|
|
||||||
static const char clks_kbd_map[128] = {
|
static const char clks_kbd_map[128] = {
|
||||||
@@ -47,10 +48,10 @@ static const char clks_kbd_shift_map[128] = {
|
|||||||
[51] = '<', [52] = '>', [53] = '?', [57] = ' '
|
[51] = '<', [52] = '>', [53] = '?', [57] = ' '
|
||||||
};
|
};
|
||||||
|
|
||||||
static char clks_kbd_input_queue[CLKS_KBD_INPUT_CAP];
|
static char clks_kbd_input_queue[CLKS_KBD_TTY_MAX][CLKS_KBD_INPUT_CAP];
|
||||||
static u16 clks_kbd_input_head = 0U;
|
static u16 clks_kbd_input_head[CLKS_KBD_TTY_MAX];
|
||||||
static u16 clks_kbd_input_tail = 0U;
|
static u16 clks_kbd_input_tail[CLKS_KBD_TTY_MAX];
|
||||||
static u16 clks_kbd_input_count = 0U;
|
static u16 clks_kbd_input_count[CLKS_KBD_TTY_MAX];
|
||||||
|
|
||||||
static clks_bool clks_kbd_alt_down = CLKS_FALSE;
|
static clks_bool clks_kbd_alt_down = CLKS_FALSE;
|
||||||
static clks_bool clks_kbd_lshift_down = CLKS_FALSE;
|
static clks_bool clks_kbd_lshift_down = CLKS_FALSE;
|
||||||
@@ -62,6 +63,30 @@ static u64 clks_kbd_push_count = 0ULL;
|
|||||||
static u64 clks_kbd_pop_count = 0ULL;
|
static u64 clks_kbd_pop_count = 0ULL;
|
||||||
static u64 clks_kbd_drop_count = 0ULL;
|
static u64 clks_kbd_drop_count = 0ULL;
|
||||||
|
|
||||||
|
static u32 clks_keyboard_effective_tty_count(void) {
|
||||||
|
u32 tty_count = clks_tty_count();
|
||||||
|
|
||||||
|
if (tty_count == 0U) {
|
||||||
|
return 1U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tty_count > CLKS_KBD_TTY_MAX) {
|
||||||
|
return CLKS_KBD_TTY_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tty_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 clks_keyboard_clamp_tty_index(u32 tty_index) {
|
||||||
|
u32 tty_count = clks_keyboard_effective_tty_count();
|
||||||
|
|
||||||
|
if (tty_index >= tty_count) {
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tty_index;
|
||||||
|
}
|
||||||
|
|
||||||
static char clks_keyboard_translate_ext_scancode(u8 code) {
|
static char clks_keyboard_translate_ext_scancode(u8 code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case CLKS_SC_EXT_LEFT:
|
case CLKS_SC_EXT_LEFT:
|
||||||
@@ -83,21 +108,24 @@ static char clks_keyboard_translate_ext_scancode(u8 code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static clks_bool clks_keyboard_queue_push(char ch) {
|
static clks_bool clks_keyboard_queue_push_for_tty(u32 tty_index, char ch) {
|
||||||
if (clks_kbd_input_count >= CLKS_KBD_INPUT_CAP) {
|
u32 tty = clks_keyboard_clamp_tty_index(tty_index);
|
||||||
|
|
||||||
|
if (clks_kbd_input_count[tty] >= CLKS_KBD_INPUT_CAP) {
|
||||||
clks_kbd_drop_count++;
|
clks_kbd_drop_count++;
|
||||||
|
|
||||||
if ((clks_kbd_drop_count % CLKS_KBD_DROP_LOG_EVERY) == 1ULL) {
|
if ((clks_kbd_drop_count % CLKS_KBD_DROP_LOG_EVERY) == 1ULL) {
|
||||||
clks_log(CLKS_LOG_WARN, "KBD", "INPUT QUEUE OVERFLOW");
|
clks_log(CLKS_LOG_WARN, "KBD", "INPUT QUEUE OVERFLOW");
|
||||||
|
clks_log_hex(CLKS_LOG_WARN, "KBD", "TTY", (u64)tty);
|
||||||
clks_log_hex(CLKS_LOG_WARN, "KBD", "DROPPED", clks_kbd_drop_count);
|
clks_log_hex(CLKS_LOG_WARN, "KBD", "DROPPED", clks_kbd_drop_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_kbd_input_queue[clks_kbd_input_head] = ch;
|
clks_kbd_input_queue[tty][clks_kbd_input_head[tty]] = ch;
|
||||||
clks_kbd_input_head = (u16)((clks_kbd_input_head + 1U) % CLKS_KBD_INPUT_CAP);
|
clks_kbd_input_head[tty] = (u16)((clks_kbd_input_head[tty] + 1U) % CLKS_KBD_INPUT_CAP);
|
||||||
clks_kbd_input_count++;
|
clks_kbd_input_count[tty]++;
|
||||||
clks_kbd_push_count++;
|
clks_kbd_push_count++;
|
||||||
return CLKS_TRUE;
|
return CLKS_TRUE;
|
||||||
}
|
}
|
||||||
@@ -131,9 +159,14 @@ static char clks_keyboard_translate_scancode(u8 code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clks_keyboard_init(void) {
|
void clks_keyboard_init(void) {
|
||||||
clks_kbd_input_head = 0U;
|
u32 tty;
|
||||||
clks_kbd_input_tail = 0U;
|
|
||||||
clks_kbd_input_count = 0U;
|
for (tty = 0U; tty < CLKS_KBD_TTY_MAX; tty++) {
|
||||||
|
clks_kbd_input_head[tty] = 0U;
|
||||||
|
clks_kbd_input_tail[tty] = 0U;
|
||||||
|
clks_kbd_input_count[tty] = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
clks_kbd_alt_down = CLKS_FALSE;
|
clks_kbd_alt_down = CLKS_FALSE;
|
||||||
clks_kbd_lshift_down = CLKS_FALSE;
|
clks_kbd_lshift_down = CLKS_FALSE;
|
||||||
clks_kbd_rshift_down = CLKS_FALSE;
|
clks_kbd_rshift_down = CLKS_FALSE;
|
||||||
@@ -184,10 +217,13 @@ void clks_keyboard_handle_scancode(u8 scancode) {
|
|||||||
|
|
||||||
if (clks_kbd_e0_prefix == CLKS_TRUE) {
|
if (clks_kbd_e0_prefix == CLKS_TRUE) {
|
||||||
char ext = clks_keyboard_translate_ext_scancode(code);
|
char ext = clks_keyboard_translate_ext_scancode(code);
|
||||||
|
u32 active_tty = clks_tty_active();
|
||||||
|
|
||||||
clks_kbd_e0_prefix = CLKS_FALSE;
|
clks_kbd_e0_prefix = CLKS_FALSE;
|
||||||
|
|
||||||
if (ext != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
|
if (ext != '\0') {
|
||||||
if (clks_keyboard_queue_push(ext) == CLKS_TRUE && clks_keyboard_should_pump_shell_now() == CLKS_TRUE) {
|
if (clks_keyboard_queue_push_for_tty(active_tty, ext) == CLKS_TRUE &&
|
||||||
|
clks_keyboard_should_pump_shell_now() == CLKS_TRUE) {
|
||||||
clks_shell_pump_input(1U);
|
clks_shell_pump_input(1U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,9 +251,11 @@ void clks_keyboard_handle_scancode(u8 scancode) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
char translated = clks_keyboard_translate_scancode(code);
|
char translated = clks_keyboard_translate_scancode(code);
|
||||||
|
u32 active_tty = clks_tty_active();
|
||||||
|
|
||||||
if (translated != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
|
if (translated != '\0') {
|
||||||
if (clks_keyboard_queue_push(translated) == CLKS_TRUE && clks_keyboard_should_pump_shell_now() == CLKS_TRUE) {
|
if (clks_keyboard_queue_push_for_tty(active_tty, translated) == CLKS_TRUE &&
|
||||||
|
clks_keyboard_should_pump_shell_now() == CLKS_TRUE) {
|
||||||
clks_shell_pump_input(1U);
|
clks_shell_pump_input(1U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,20 +266,33 @@ u64 clks_keyboard_hotkey_switch_count(void) {
|
|||||||
return clks_kbd_hotkey_switches;
|
return clks_kbd_hotkey_switches;
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_bool clks_keyboard_pop_char(char *out_ch) {
|
clks_bool clks_keyboard_pop_char_for_tty(u32 tty_index, char *out_ch) {
|
||||||
if (out_ch == CLKS_NULL || clks_kbd_input_count == 0U) {
|
u32 tty = clks_keyboard_clamp_tty_index(tty_index);
|
||||||
|
|
||||||
|
if (out_ch == CLKS_NULL || clks_kbd_input_count[tty] == 0U) {
|
||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_ch = clks_kbd_input_queue[clks_kbd_input_tail];
|
*out_ch = clks_kbd_input_queue[tty][clks_kbd_input_tail[tty]];
|
||||||
clks_kbd_input_tail = (u16)((clks_kbd_input_tail + 1U) % CLKS_KBD_INPUT_CAP);
|
clks_kbd_input_tail[tty] = (u16)((clks_kbd_input_tail[tty] + 1U) % CLKS_KBD_INPUT_CAP);
|
||||||
clks_kbd_input_count--;
|
clks_kbd_input_count[tty]--;
|
||||||
clks_kbd_pop_count++;
|
clks_kbd_pop_count++;
|
||||||
return CLKS_TRUE;
|
return CLKS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clks_bool clks_keyboard_pop_char(char *out_ch) {
|
||||||
|
return clks_keyboard_pop_char_for_tty(clks_tty_active(), out_ch);
|
||||||
|
}
|
||||||
|
|
||||||
u64 clks_keyboard_buffered_count(void) {
|
u64 clks_keyboard_buffered_count(void) {
|
||||||
return (u64)clks_kbd_input_count;
|
u64 total = 0ULL;
|
||||||
|
u32 tty;
|
||||||
|
|
||||||
|
for (tty = 0U; tty < CLKS_KBD_TTY_MAX; tty++) {
|
||||||
|
total += (u64)clks_kbd_input_count[tty];
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 clks_keyboard_drop_count(void) {
|
u64 clks_keyboard_drop_count(void) {
|
||||||
@@ -255,4 +306,3 @@ u64 clks_keyboard_push_count(void) {
|
|||||||
u64 clks_keyboard_pop_count(void) {
|
u64 clks_keyboard_pop_count(void) {
|
||||||
return clks_kbd_pop_count;
|
return clks_kbd_pop_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void clks_kernel_main(void) {
|
|||||||
clks_tty_init();
|
clks_tty_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS Stage28 START");
|
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS Stage29 START");
|
||||||
|
|
||||||
if (boot_fb == CLKS_NULL) {
|
if (boot_fb == CLKS_NULL) {
|
||||||
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
||||||
|
|||||||
@@ -128,8 +128,9 @@ static u64 clks_syscall_tty_write_char(u64 arg0) {
|
|||||||
|
|
||||||
static u64 clks_syscall_kbd_get_char(void) {
|
static u64 clks_syscall_kbd_get_char(void) {
|
||||||
char ch;
|
char ch;
|
||||||
|
u32 tty_index = clks_exec_current_tty();
|
||||||
|
|
||||||
if (clks_keyboard_pop_char(&ch) == CLKS_FALSE) {
|
if (clks_keyboard_pop_char_for_tty(tty_index, &ch) == CLKS_FALSE) {
|
||||||
return (u64)-1;
|
return (u64)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
- `stage26.md`
|
- `stage26.md`
|
||||||
- `stage27.md`
|
- `stage27.md`
|
||||||
- `stage28.md`
|
- `stage28.md`
|
||||||
|
- `stage29.md`
|
||||||
|
|
||||||
- `syscall.md` (syscall ABI reference)
|
- `syscall.md` (syscall ABI reference)
|
||||||
|
|
||||||
|
|||||||
39
docs/stage29.md
Normal file
39
docs/stage29.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Stage 29 - Async Exec Dispatch + TTY-Bound Input Ownership
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
- Make process launch lifecycle explicit (`pending -> running -> exited`) and tick-driven.
|
||||||
|
- Bind user input to the process TTY context to avoid cross-TTY input stealing.
|
||||||
|
- Keep kernel shell input compatibility while preparing cleaner multi-TTY user-shell behavior.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
- Exec lifecycle (Stage 29A):
|
||||||
|
- Added process states: `CLKS_EXEC_PROC_PENDING`, `CLKS_EXEC_PROC_RUNNING`, `CLKS_EXEC_PROC_EXITED`.
|
||||||
|
- `clks_exec_spawn_path()` now queues process records as pending.
|
||||||
|
- Added `clks_exec_tick()` to dispatch pending processes from scheduler tick context.
|
||||||
|
- `waitpid` now understands pending/running/exited transitions.
|
||||||
|
- TTY ownership (Stage 29B):
|
||||||
|
- Added `tty_index` to exec process record and capture active TTY when process is created.
|
||||||
|
- Added `clks_exec_current_tty()` to resolve the current execution TTY safely.
|
||||||
|
- Refactored keyboard input buffer to per-TTY ring queues.
|
||||||
|
- Added `clks_keyboard_pop_char_for_tty()` API.
|
||||||
|
- Updated syscall keyboard read path to pop from `clks_exec_current_tty()` queue.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- `spawn` no longer blocks immediate caller flow and enters pending lifecycle.
|
||||||
|
- Tick loop dispatches pending processes without recursive launch storm.
|
||||||
|
- Keyboard input on one TTY is not consumed by process context on another TTY.
|
||||||
|
- Kernel shell input remains functional through existing `clks_keyboard_pop_char()` API.
|
||||||
|
|
||||||
|
## Build Targets
|
||||||
|
- `make userapps`
|
||||||
|
- `make ramdisk`
|
||||||
|
- `make iso`
|
||||||
|
- `make run`
|
||||||
|
|
||||||
|
## QEMU Command
|
||||||
|
- `make run`
|
||||||
|
|
||||||
|
## Debug Notes
|
||||||
|
- If user shell appears to miss input, log `clks_exec_current_tty()` and active TTY during syscall `KBD_GET_CHAR`.
|
||||||
|
- If input is delayed, inspect queue depth via `kbdstat` and verify per-TTY counters move.
|
||||||
|
- If `waitpid` stalls forever, check whether `clks_exec_tick()` is called in scheduler/user service tick.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Stage13 shell init script for CLeonOS
|
# Stage13 shell init script for CLeonOS
|
||||||
# Lines starting with # are comments.
|
# Lines starting with # are comments.
|
||||||
|
|
||||||
help
|
# help
|
||||||
stats
|
# stats
|
||||||
|
|||||||
Reference in New Issue
Block a user