diff --git a/TODO b/TODO index 614397f..d03bff9 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,3 @@ -switch from parted to gdisk lsstat to decrease tests size separate dirs for each image and test library loader diff --git a/apps/makefile b/apps/makefile index fd51837..699fb1a 100644 --- a/apps/makefile +++ b/apps/makefile @@ -8,7 +8,7 @@ else ifeq ($(HOST),windows) FASM_INCLUDE=$(KOLIBRIOS)\programs FASM=set "INCLUDE=$(FASM_INCLUDE)" && $(FASM_EXE) $(FASM_FLAGS) else - $(error your OS is not supported) + $(error your HOST is not supported) endif all: board_hello board_cycle readdir loader justawindow diff --git a/shell.c b/shell.c index 6b04653..0c7efd6 100644 --- a/shell.c +++ b/shell.c @@ -55,6 +55,8 @@ enum { UMKA_CMD_NONE, UMKA_CMD_SET_MOUSE_DATA, UMKA_CMD_WAIT_FOR_IDLE, + UMKA_CMD_WAIT_FOR_OS_IDLE, + UMKA_CMD_WAIT_FOR_WINDOW, UMKA_CMD_SYS_CSLEEP, UMKA_CMD_SYS_PROCESS_INFO, UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN, @@ -139,12 +141,26 @@ struct cmd_sys_csleep { 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 { atomic_int status; uint32_t type; union { // internal funcs struct cmd_set_mouse_data set_mouse_data; + struct cmd_wait_for_window wait_for_window; // syscalls struct cmd_sys_csleep sys_csleep; struct cmd_sys_process_info sys_process_info; @@ -170,7 +186,10 @@ shell_run_cmd_sync(struct shell_ctx *ctx); static void 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); } else { 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) { char *stack = malloc(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; } } @@ -617,8 +637,6 @@ cmd_csleep(struct shell_ctx *ctx, int argc, char **argv) { struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg; cmd->type = UMKA_CMD_SYS_CSLEEP; c->csec = strtoul(argv[1], NULL, 0); - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, - memory_order_release); shell_run_cmd(ctx); atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, memory_order_release); @@ -626,12 +644,12 @@ cmd_csleep(struct shell_ctx *ctx, int argc, char **argv) { static uint32_t 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 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); } @@ -646,8 +664,73 @@ cmd_wait_for_idle(struct shell_ctx *ctx, int argc, char **argv) { } struct umka_cmd *cmd = umka_cmd_buf; 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); +} + +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 \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); atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, memory_order_release); @@ -1285,10 +1368,7 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { c->ymoving = ymoving; c->vscroll = vscroll; c->hscroll = hscroll; - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, - memory_order_release); shell_run_cmd(ctx); - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, memory_order_release); } @@ -2516,11 +2596,7 @@ ls_all(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) { c->bufptr = fX0; c->r = &r; - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, - memory_order_release); - COVERAGE_ON(); shell_run_cmd(ctx); - COVERAGE_OFF(); atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, memory_order_release); print_f70_status(ctx, &r, 1); @@ -4131,6 +4207,8 @@ func_table_t cmd_cmds[] = { { "var", cmd_var }, { "check_for_event", cmd_check_for_event }, { "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 }, { "write_text", cmd_write_text }, { "switch_to_thread", cmd_switch_to_thread }, @@ -4141,10 +4219,6 @@ func_table_t cmd_cmds[] = { void shell_run_cmd_sync(struct shell_ctx *ctx) { 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) { case UMKA_CMD_WAIT_FOR_IDLE: { COVERAGE_ON(); @@ -4152,6 +4226,19 @@ shell_run_cmd_sync(struct shell_ctx *ctx) { COVERAGE_OFF(); 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: { struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg; COVERAGE_ON(); diff --git a/umka.asm b/umka.asm index 993a07f..25cfa2a 100644 --- a/umka.asm +++ b/umka.asm @@ -100,7 +100,8 @@ UMKA_BOOT_DEFAULT_DISPLAY_BPP = 32 UMKA_BOOT_DEFAULT_DISPLAY_WIDTH = 400 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 idts, 'kos_idts' pubsym attach_int_handler, 'kos_attach_int_handler', 12 @@ -886,7 +887,7 @@ proc idle uses ebx esi edi extrn "pause", 0, libc_pause sti @@: - mov [idle_reached], 1 + mov [idle_scheduled], 1 sfence call libc_pause jmp @b @@ -1083,6 +1084,7 @@ bios32_entry equ bios32_entry_pew tmp_page_tabs equ tmp_page_tabs_pew macro jmp target { if target eq osloop + mov [os_scheduled], 1 cmp [umka.running], UMKA_RUNNIGS_YES jz osloop ret @@ -1125,7 +1127,8 @@ section '.data.64' writeable align 0x1000 umka umka_ctx 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 section '.bss.mem' writeable align 0x1000 diff --git a/umka.h b/umka.h index 70e3cb2..7e52df1 100644 --- a/umka.h +++ b/umka.h @@ -67,6 +67,14 @@ enum kos_lang { 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 BDFE_LEN_CP866 304 @@ -573,7 +581,8 @@ disk_del(disk_t *disk); void 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 ext_user_functions[]; @@ -944,11 +953,6 @@ typedef struct { 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 size_t kos_task_count; 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 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; size_t tid = kos_new_sys_threads(flags, entry_noparam, stack_top); 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 // -12 here because in UMKa, unlike real hardware, we don't switch between // 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), "c"(4), "d"(new_pos) - :); + : "memory"); } static inline int diff --git a/umka_os.c b/umka_os.c index 1c6033e..d6fc88e 100644 --- a/umka_os.c +++ b/umka_os.c @@ -96,6 +96,12 @@ dump_procs(void) { } while (p != p_begin); 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 @@ -417,9 +423,9 @@ main(int argc, char *argv[]) { 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); - atomic_store_explicit(&os->umka->running, UMKA_RUNNING_YES, memory_order_release); umka_osloop(); // doesn't return if (coverage)