Add shell commands wait_for_os_idle, wait_for_window

This commit is contained in:
2023-02-13 23:48:48 +00:00
parent 40fa7218b1
commit ab563f3db9
6 changed files with 132 additions and 32 deletions

1
TODO
View File

@@ -1,4 +1,3 @@
switch from parted to gdisk
lsstat to decrease tests size lsstat to decrease tests size
separate dirs for each image and test separate dirs for each image and test
library loader library loader

View File

@@ -8,7 +8,7 @@ else ifeq ($(HOST),windows)
FASM_INCLUDE=$(KOLIBRIOS)\programs FASM_INCLUDE=$(KOLIBRIOS)\programs
FASM=set "INCLUDE=$(FASM_INCLUDE)" && $(FASM_EXE) $(FASM_FLAGS) FASM=set "INCLUDE=$(FASM_INCLUDE)" && $(FASM_EXE) $(FASM_FLAGS)
else else
$(error your OS is not supported) $(error your HOST is not supported)
endif endif
all: board_hello board_cycle readdir loader justawindow all: board_hello board_cycle readdir loader justawindow

123
shell.c
View File

@@ -55,6 +55,8 @@ enum {
UMKA_CMD_NONE, UMKA_CMD_NONE,
UMKA_CMD_SET_MOUSE_DATA, UMKA_CMD_SET_MOUSE_DATA,
UMKA_CMD_WAIT_FOR_IDLE, UMKA_CMD_WAIT_FOR_IDLE,
UMKA_CMD_WAIT_FOR_OS_IDLE,
UMKA_CMD_WAIT_FOR_WINDOW,
UMKA_CMD_SYS_CSLEEP, UMKA_CMD_SYS_CSLEEP,
UMKA_CMD_SYS_PROCESS_INFO, UMKA_CMD_SYS_PROCESS_INFO,
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN, UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
@@ -139,12 +141,26 @@ struct cmd_sys_csleep {
struct cmd_sys_csleep_ret ret; struct cmd_sys_csleep_ret ret;
}; };
struct cmd_wait_for_window_arg {
char *wnd_title;
};
struct cmd_wait_for_window_ret {
char stub;
};
struct cmd_wait_for_window {
struct cmd_wait_for_window_arg arg;
struct cmd_wait_for_window_ret ret;
};
struct umka_cmd { struct umka_cmd {
atomic_int status; atomic_int status;
uint32_t type; uint32_t type;
union { union {
// internal funcs // internal funcs
struct cmd_set_mouse_data set_mouse_data; struct cmd_set_mouse_data set_mouse_data;
struct cmd_wait_for_window wait_for_window;
// syscalls // syscalls
struct cmd_sys_csleep sys_csleep; struct cmd_sys_csleep sys_csleep;
struct cmd_sys_process_info sys_process_info; struct cmd_sys_process_info sys_process_info;
@@ -170,7 +186,10 @@ shell_run_cmd_sync(struct shell_ctx *ctx);
static void static void
shell_run_cmd(struct shell_ctx *ctx) { shell_run_cmd(struct shell_ctx *ctx) {
if (atomic_load_explicit(ctx->running, memory_order_acquire)) { struct umka_cmd *cmd = umka_cmd_buf;
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
if (atomic_load_explicit(ctx->running, memory_order_acquire) == UMKA_RUNNING_YES) {
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex); pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
} else { } else {
shell_run_cmd_sync(ctx); shell_run_cmd_sync(ctx);
@@ -558,7 +577,8 @@ cmd_umka_boot(struct shell_ctx *ctx, int argc, char **argv) {
if (*ctx->running != UMKA_RUNNING_NEVER) { if (*ctx->running != UMKA_RUNNING_NEVER) {
char *stack = malloc(UMKA_DEFAULT_THREAD_STACK_SIZE); char *stack = malloc(UMKA_DEFAULT_THREAD_STACK_SIZE);
char *stack_top = stack + UMKA_DEFAULT_THREAD_STACK_SIZE; char *stack_top = stack + UMKA_DEFAULT_THREAD_STACK_SIZE;
size_t tid = umka_new_sys_threads(0, thread_cmd_runner, stack_top, ctx); size_t tid = umka_new_sys_threads(0, thread_cmd_runner, stack_top, ctx,
"cmd_runner");
(void)tid; (void)tid;
} }
} }
@@ -617,8 +637,6 @@ cmd_csleep(struct shell_ctx *ctx, int argc, char **argv) {
struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg; struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg;
cmd->type = UMKA_CMD_SYS_CSLEEP; cmd->type = UMKA_CMD_SYS_CSLEEP;
c->csec = strtoul(argv[1], NULL, 0); c->csec = strtoul(argv[1], NULL, 0);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
shell_run_cmd(ctx); shell_run_cmd(ctx);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release); memory_order_release);
@@ -626,12 +644,12 @@ cmd_csleep(struct shell_ctx *ctx, int argc, char **argv) {
static uint32_t static uint32_t
umka_wait_for_idle_test(void) { umka_wait_for_idle_test(void) {
return (uint32_t)(atomic_load_explicit(&idle_reached, memory_order_acquire)); return (uint32_t)(atomic_load_explicit(&idle_scheduled, memory_order_acquire));
} }
static void static void
umka_wait_for_idle(void) { umka_wait_for_idle(void) {
atomic_store_explicit(&idle_reached, 0, memory_order_release); atomic_store_explicit(&idle_scheduled, 0, memory_order_release);
kos_wait_events(umka_wait_for_idle_test, NULL); kos_wait_events(umka_wait_for_idle_test, NULL);
} }
@@ -646,8 +664,73 @@ cmd_wait_for_idle(struct shell_ctx *ctx, int argc, char **argv) {
} }
struct umka_cmd *cmd = umka_cmd_buf; struct umka_cmd *cmd = umka_cmd_buf;
cmd->type = UMKA_CMD_WAIT_FOR_IDLE; cmd->type = UMKA_CMD_WAIT_FOR_IDLE;
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, shell_run_cmd(ctx);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release); memory_order_release);
}
static uint32_t
umka_wait_for_os_test(void) {
return (uint32_t)(atomic_load_explicit(&os_scheduled, memory_order_acquire));
}
static void
umka_wait_for_os_idle(void) {
atomic_store_explicit(&os_scheduled, 0, memory_order_release);
kos_wait_events(umka_wait_for_os_test, NULL);
atomic_store_explicit(&idle_scheduled, 0, memory_order_release);
kos_wait_events(umka_wait_for_idle_test, NULL);
}
static void
cmd_wait_for_os_idle(struct shell_ctx *ctx, int argc, char **argv) {
(void)argv;
const char *usage = \
"usage: wait_for_os_idle\n";
if (argc != 1) {
fputs(usage, ctx->fout);
return;
}
struct umka_cmd *cmd = umka_cmd_buf;
cmd->type = UMKA_CMD_WAIT_FOR_OS_IDLE;
shell_run_cmd(ctx);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release);
}
static uint32_t
umka_wait_for_window_test(void) {
appdata_t *app;
__asm__ __volatile__ __inline__ ("":"=b"(app)::);
const char *wnd_title = (const char *)app->wait_param;
for (size_t i = 0; i < 256; i++) {
app = kos_slot_base + i;
if (app->state != KOS_TSTATE_FREE && app->wnd_caption
&& !strcmp(app->wnd_caption, wnd_title)) {
return 1;
}
}
return 0;
}
static void
umka_wait_for_window(char *wnd_title) {
kos_wait_events(umka_wait_for_window_test, wnd_title);
}
static void
cmd_wait_for_window(struct shell_ctx *ctx, int argc, char **argv) {
(void)argv;
const char *usage = \
"usage: wait_for_window <window_title>\n";
if (argc != 2) {
fputs(usage, ctx->fout);
return;
}
struct umka_cmd *cmd = umka_cmd_buf;
cmd->type = UMKA_CMD_WAIT_FOR_WINDOW;
struct cmd_wait_for_window_arg *c = &cmd->wait_for_window.arg;
c->wnd_title = argv[1];
shell_run_cmd(ctx); shell_run_cmd(ctx);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release); memory_order_release);
@@ -1285,10 +1368,7 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) {
c->ymoving = ymoving; c->ymoving = ymoving;
c->vscroll = vscroll; c->vscroll = vscroll;
c->hscroll = hscroll; c->hscroll = hscroll;
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
shell_run_cmd(ctx); shell_run_cmd(ctx);
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release); memory_order_release);
} }
@@ -2516,11 +2596,7 @@ ls_all(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) {
c->bufptr = fX0; c->bufptr = fX0;
c->r = &r; c->r = &r;
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
COVERAGE_ON();
shell_run_cmd(ctx); shell_run_cmd(ctx);
COVERAGE_OFF();
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release); memory_order_release);
print_f70_status(ctx, &r, 1); print_f70_status(ctx, &r, 1);
@@ -4131,6 +4207,8 @@ func_table_t cmd_cmds[] = {
{ "var", cmd_var }, { "var", cmd_var },
{ "check_for_event", cmd_check_for_event }, { "check_for_event", cmd_check_for_event },
{ "wait_for_idle", cmd_wait_for_idle }, { "wait_for_idle", cmd_wait_for_idle },
{ "wait_for_os_idle", cmd_wait_for_os_idle },
{ "wait_for_window", cmd_wait_for_window },
{ "window_redraw", cmd_window_redraw }, { "window_redraw", cmd_window_redraw },
{ "write_text", cmd_write_text }, { "write_text", cmd_write_text },
{ "switch_to_thread", cmd_switch_to_thread }, { "switch_to_thread", cmd_switch_to_thread },
@@ -4141,10 +4219,6 @@ func_table_t cmd_cmds[] = {
void void
shell_run_cmd_sync(struct shell_ctx *ctx) { shell_run_cmd_sync(struct shell_ctx *ctx) {
struct umka_cmd *cmd = umka_cmd_buf; struct umka_cmd *cmd = umka_cmd_buf;
if (atomic_load_explicit(&cmd->status, memory_order_acquire) != SHELL_CMD_STATUS_READY) {
fprintf(ctx->fout, "[!] command is not ready: %d: %u\n", cmd - umka_cmd_buf, cmd->type);
return;
}
switch (cmd->type) { switch (cmd->type) {
case UMKA_CMD_WAIT_FOR_IDLE: { case UMKA_CMD_WAIT_FOR_IDLE: {
COVERAGE_ON(); COVERAGE_ON();
@@ -4152,6 +4226,19 @@ shell_run_cmd_sync(struct shell_ctx *ctx) {
COVERAGE_OFF(); COVERAGE_OFF();
break; break;
} }
case UMKA_CMD_WAIT_FOR_OS_IDLE: {
COVERAGE_ON();
umka_wait_for_os_idle();
COVERAGE_OFF();
break;
}
case UMKA_CMD_WAIT_FOR_WINDOW: {
struct cmd_wait_for_window_arg *c = &cmd->wait_for_window.arg;
COVERAGE_ON();
umka_wait_for_window(c->wnd_title);
COVERAGE_OFF();
break;
}
case UMKA_CMD_SYS_CSLEEP: { case UMKA_CMD_SYS_CSLEEP: {
struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg; struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg;
COVERAGE_ON(); COVERAGE_ON();

View File

@@ -100,7 +100,8 @@ UMKA_BOOT_DEFAULT_DISPLAY_BPP = 32
UMKA_BOOT_DEFAULT_DISPLAY_WIDTH = 400 UMKA_BOOT_DEFAULT_DISPLAY_WIDTH = 400
UMKA_BOOT_DEFAULT_DISPLAY_HEIGHT = 300 UMKA_BOOT_DEFAULT_DISPLAY_HEIGHT = 300
public idle_reached public idle_scheduled
public os_scheduled
pubsym irq_serv.irq_10, 'kos_irq_serv_irq10' pubsym irq_serv.irq_10, 'kos_irq_serv_irq10'
pubsym idts, 'kos_idts' pubsym idts, 'kos_idts'
pubsym attach_int_handler, 'kos_attach_int_handler', 12 pubsym attach_int_handler, 'kos_attach_int_handler', 12
@@ -886,7 +887,7 @@ proc idle uses ebx esi edi
extrn "pause", 0, libc_pause extrn "pause", 0, libc_pause
sti sti
@@: @@:
mov [idle_reached], 1 mov [idle_scheduled], 1
sfence sfence
call libc_pause call libc_pause
jmp @b jmp @b
@@ -1083,6 +1084,7 @@ bios32_entry equ bios32_entry_pew
tmp_page_tabs equ tmp_page_tabs_pew tmp_page_tabs equ tmp_page_tabs_pew
macro jmp target { macro jmp target {
if target eq osloop if target eq osloop
mov [os_scheduled], 1
cmp [umka.running], UMKA_RUNNIGS_YES cmp [umka.running], UMKA_RUNNIGS_YES
jz osloop jz osloop
ret ret
@@ -1125,7 +1127,8 @@ section '.data.64' writeable align 0x1000
umka umka_ctx umka umka_ctx
fpu_owner dd ? fpu_owner dd ?
idle_reached dd ? idle_scheduled dd ?
os_scheduled dd ?
; mem for memory; otherwide fasm complains with 'name too long' for MS COFF ; mem for memory; otherwide fasm complains with 'name too long' for MS COFF
section '.bss.mem' writeable align 0x1000 section '.bss.mem' writeable align 0x1000

21
umka.h
View File

@@ -67,6 +67,14 @@ enum kos_lang {
KOS_LANG_LAST = KOS_LANG_CA KOS_LANG_LAST = KOS_LANG_CA
}; };
#define KOS_TSTATE_RUNNING 0
#define KOS_TSTATE_RUN_SUSPENDED 1
#define KOS_TSTATE_WAIT_SUSPENDED 2
#define KOS_TSTATE_ZOMBIE 3
#define KOS_TSTATE_TERMINATING 4
#define KOS_TSTATE_WAITING 5
#define KOS_TSTATE_FREE 9
#define KOS_LAYOUT_SIZE 128 #define KOS_LAYOUT_SIZE 128
#define BDFE_LEN_CP866 304 #define BDFE_LEN_CP866 304
@@ -573,7 +581,8 @@ disk_del(disk_t *disk);
void void
hash_oneshot(void *ctx, void *data, size_t len); hash_oneshot(void *ctx, void *data, size_t len);
extern atomic_int idle_reached; extern atomic_int idle_scheduled;
extern atomic_int os_scheduled;
extern uint8_t xfs_user_functions[]; extern uint8_t xfs_user_functions[];
extern uint8_t ext_user_functions[]; extern uint8_t ext_user_functions[];
@@ -944,11 +953,6 @@ typedef struct {
static_assert(sizeof(appdata_t) == 256, "must be 0x100 bytes long"); static_assert(sizeof(appdata_t) == 256, "must be 0x100 bytes long");
#define UMKA_SHELL 1
#define UMKA_FUSE 2
#define UMKA_OS 3
#define UMKA_GEN_DEVICES_DAT 4
extern uint8_t kos_redraw_background; extern uint8_t kos_redraw_background;
extern size_t kos_task_count; extern size_t kos_task_count;
extern wdata_t kos_window_data[]; extern wdata_t kos_window_data[];
@@ -1141,10 +1145,11 @@ kos_new_sys_threads(uint32_t flags, kos_thread_t entry, void *stack_top) {
static inline size_t static inline size_t
umka_new_sys_threads(uint32_t flags, void (*entry)(void *), void *stack_top, umka_new_sys_threads(uint32_t flags, void (*entry)(void *), void *stack_top,
void *arg) { void *arg, const char *app_name) {
kos_thread_t entry_noparam = (kos_thread_t)entry; kos_thread_t entry_noparam = (kos_thread_t)entry;
size_t tid = kos_new_sys_threads(flags, entry_noparam, stack_top); size_t tid = kos_new_sys_threads(flags, entry_noparam, stack_top);
appdata_t *t = kos_slot_base + tid; appdata_t *t = kos_slot_base + tid;
strncpy(t->app_name, app_name, 11);
*(void**)((char*)t->saved_esp0-12) = arg; // param for the thread *(void**)((char*)t->saved_esp0-12) = arg; // param for the thread
// -12 here because in UMKa, unlike real hardware, we don't switch between // -12 here because in UMKa, unlike real hardware, we don't switch between
// kernel and userspace, i.e. stack structure is different // kernel and userspace, i.e. stack structure is different
@@ -1434,7 +1439,7 @@ umka_sys_set_mouse_pos_screen(struct point16s new_pos) {
"b"(19), "b"(19),
"c"(4), "c"(4),
"d"(new_pos) "d"(new_pos)
:); : "memory");
} }
static inline int static inline int

View File

@@ -96,6 +96,12 @@ dump_procs(void) {
} while (p != p_begin); } while (p != p_begin);
putchar('\n'); putchar('\n');
} }
for (size_t i = 0; i < 256; i++) {
appdata_t *app = kos_slot_base + i;
if (app->state != KOS_TSTATE_FREE && app->app_name[0]) {
printf("slot %2.2d: %s\n", i, app->app_name);
}
}
} }
int int
@@ -417,9 +423,9 @@ main(int argc, char *argv[]) {
pthread_create(&thread_display, NULL, umka_display, NULL); pthread_create(&thread_display, NULL, umka_display, NULL);
} }
atomic_store_explicit(&os->umka->running, UMKA_RUNNING_YES, memory_order_release);
setitimer(ITIMER_REAL, &timeout, NULL); setitimer(ITIMER_REAL, &timeout, NULL);
atomic_store_explicit(&os->umka->running, UMKA_RUNNING_YES, memory_order_release);
umka_osloop(); // doesn't return umka_osloop(); // doesn't return
if (coverage) if (coverage)