[umka_os] Add a command console in a separate thread

This commit is contained in:
Ivan Baravy 2023-02-10 22:33:22 +00:00
parent bd46201f6a
commit 8883b1c5de
17 changed files with 358 additions and 355 deletions

View File

@ -607,7 +607,7 @@ typedef void (ic_free_fun_t)( void* p );
/// Initialize with custom allocation functions.
/// This must be called as the first function in a program!
void ic_init_custom_alloc( ic_malloc_fun_t* _malloc, ic_realloc_fun_t* _realloc, ic_free_fun_t* _free );
void ic_init_custom_malloc( ic_malloc_fun_t* _malloc, ic_realloc_fun_t* _realloc, ic_free_fun_t* _free );
/// Free a potentially custom alloc'd pointer (in particular, the result returned from `ic_readline`)
void ic_free( void* p );

View File

@ -565,7 +565,7 @@ static signal_handler_t sighandlers[] = {
{ SIGINT , {0} },
{ SIGQUIT , {0} },
{ SIGHUP , {0} },
{ SIGSEGV , {0} },
// { SIGSEGV , {0} },
{ SIGTRAP , {0} },
{ SIGBUS , {0} },
{ SIGTSTP , {0} },

View File

@ -13,14 +13,16 @@ WARNINGS_COMMON=-Wall -Wextra \
#-Wconversion -Wsign-conversion
NOWARNINGS_COMMON=-Wno-address-of-packed-member
ifneq (,$(findstring gcc,$(CC)))
WARNINGS=$(WARNINGS_COMMON) -Wduplicated-cond -Wduplicated-branches -Wrestrict -Wlogical-op -Wjump-misses-init
NOWARNINGS=$(NOWARNINGS_COMMON)
CFLAGS_ISOCLINE=-Wno-duplicated-branches
else ifneq (,$(findstring clang,$(CC)))
CFLAGS_ISOCLINE_COMMON=-D__MINGW_USE_VC2005_COMPAT
ifeq (,$(findstring gcc,$(CC)))
WARNINGS=$(WARNINGS_COMMON)
NOWARNINGS=$(NOWARNINGS_COMMON) -Wno-missing-prototype-for-cc
CFLAGS_ISOCLINE=-Wno-format-nonliteral
CFLAGS_ISOCLINE=$(CFLAGS_ISOCLINE_COMMON) -Wno-format-nonliteral
else ifeq (,$(findstring clang,$(CC)))
WARNINGS=$(WARNINGS_COMMON) -Wduplicated-cond -Wduplicated-branches \
-Wrestrict -Wlogical-op -Wjump-misses-init
NOWARNINGS=$(NOWARNINGS_COMMON)
CFLAGS_ISOCLINE=$(CFLAGS_ISOCLINE_COMMON) -Wno-duplicated-branches
else
$(error your compiler is not supported)
endif
@ -103,7 +105,7 @@ lodepng.o: lodepng.c lodepng.h
deps/isocline/src/isocline.o: deps/isocline/src/isocline.c \
deps/isocline/include/isocline.h
$(CC) $(CFLAGS_32) -D__MINGW_USE_VC2005_COMPAT $(CFLAGS_ISOCLINE) -c $< -o $@ -Wno-shadow \
$(CC) $(CFLAGS_32) $(CFLAGS_ISOCLINE) -c $< -o $@ -Wno-shadow \
-Wno-unused-function
deps/optparse/optparse.o: deps/optparse/optparse.c deps/optparse/optparse.h

119
shell.c
View File

@ -41,8 +41,6 @@
#include "optparse/optparse.h"
#include "isocline/include/isocline.h"
char *bestlineFile(const char *prompt, FILE *fin, FILE *fout);
#define MAX_COMMAND_ARGS 42
#define PRINT_BYTES_PER_LINE 32
#define MAX_DIRENTS_TO_READ 100
@ -51,6 +49,64 @@ char *bestlineFile(const char *prompt, FILE *fin, FILE *fout);
#define DEFAULT_READDIR_ENCODING UTF8
#define DEFAULT_PATH_ENCODING UTF8
#define SHELL_CMD_BUF_LEN 0x10
enum {
UMKA_CMD_NONE,
UMKA_CMD_SET_MOUSE_DATA,
UMKA_CMD_SYS_PROCESS_INFO,
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
UMKA_CMD_SYS_LFN,
};
enum {
SHELL_CMD_STATUS_EMPTY,
SHELL_CMD_STATUS_READY,
SHELL_CMD_STATUS_DONE,
};
struct cmd_set_mouse_data {
uint32_t btn_state;
int32_t xmoving;
int32_t ymoving;
int32_t vscroll;
int32_t hscroll;
};
struct cmd_sys_lfn {
f70or80_t f70or80;
f7080s1arg_t *bufptr;
f7080ret_t *r;
};
struct cmd_ret_sys_lfn {
f7080ret_t status;
};
struct cmd_sys_process_info {
int32_t pid;
void *param;
};
struct cmd_ret_sys_get_mouse_pos_screen {
struct point16s pos;
};
struct umka_cmd {
atomic_int status;
uint32_t type;
union {
struct cmd_set_mouse_data set_mouse_data;
struct cmd_sys_lfn sys_lfn;
} arg;
union {
struct cmd_ret_sys_get_mouse_pos_screen sys_get_mouse_pos_screen;
struct cmd_ret_sys_lfn sys_lfn;
} ret;
};
struct umka_cmd umka_cmd_buf[SHELL_CMD_BUF_LEN];
char prompt_line[PATH_MAX];
char cur_dir[PATH_MAX] = "/";
const char *last_dir = cur_dir;
@ -62,9 +118,9 @@ typedef struct {
} func_table_t;
void
umka_run_cmd_sync(struct shell_ctx *ctx) {
shell_run_cmd_sync(struct shell_ctx *ctx) {
struct umka_cmd *cmd = umka_cmd_buf;
if (atomic_load_explicit(&cmd->status, memory_order_acquire) != UMKA_CMD_STATUS_READY) {
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;
}
@ -84,17 +140,35 @@ umka_run_cmd_sync(struct shell_ctx *ctx) {
fprintf(ctx->fout, "[!] unknown command: %u\n", cmd->type);
break;
}
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_DONE,
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_DONE,
memory_order_release);
pthread_cond_signal(&ctx->cmd_done);
}
static void
umka_run_cmd(struct shell_ctx *ctx) {
shell_run_cmd(struct shell_ctx *ctx) {
if (atomic_load_explicit(ctx->running, memory_order_acquire)) {
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
} else {
umka_run_cmd_sync(ctx);
shell_run_cmd_sync(ctx);
}
}
static uint32_t
shell_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) {
appdata_t *app;
__asm__ __volatile__ __inline__ ("":"=b"(app)::);
struct umka_cmd *cmd = (struct umka_cmd*)app->wait_param;
return (uint32_t)(atomic_load_explicit(&cmd->status, memory_order_acquire) == SHELL_CMD_STATUS_READY);
}
static void
thread_cmd_runner(void *arg) {
umka_sti();
struct shell_ctx *ctx = arg;
while (1) {
kos_wait_events(shell_run_cmd_wait_test, umka_cmd_buf);
shell_run_cmd_sync(ctx);
}
}
@ -457,6 +531,13 @@ cmd_umka_boot(struct shell_ctx *ctx, int argc, char **argv) {
COVERAGE_ON();
umka_boot();
COVERAGE_OFF();
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(1, thread_cmd_runner, stack_top, ctx);
(void)tid;
}
}
static void
@ -1034,7 +1115,7 @@ cmd_new_sys_thread(struct shell_ctx *ctx, int argc, char **argv) {
fputs(usage, ctx->fout);
return;
}
size_t tid = umka_new_sys_threads(0, NULL, NULL);
size_t tid = kos_new_sys_threads(0, NULL, NULL);
fprintf(ctx->fout, "tid: %u\n", tid);
}
@ -1132,13 +1213,13 @@ 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, UMKA_CMD_STATUS_READY,
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
COVERAGE_ON();
umka_run_cmd(ctx);
shell_run_cmd(ctx);
COVERAGE_OFF();
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_EMPTY,
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release);
}
@ -2360,13 +2441,12 @@ ls_all(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) {
c->bufptr = fX0;
c->r = &r;
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_READY,
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY,
memory_order_release);
COVERAGE_ON();
// umka_sys_lfn(fX0, &r, f70or80);
umka_run_cmd(ctx);
shell_run_cmd(ctx);
COVERAGE_OFF();
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_EMPTY,
atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY,
memory_order_release);
print_f70_status(ctx, &r, 1);
assert((r.status == ERROR_SUCCESS && r.count == fX0->size)
@ -3031,7 +3111,7 @@ cmd_net_get_dev(struct shell_ctx *ctx, int argc, char **argv) {
intptr_t dev = umka_sys_net_get_dev(dev_num);
COVERAGE_OFF();
fprintf(ctx->fout, "status: %s\n", dev == -1 ? "fail" : "ok");
if (dev != -1) {
if (!ctx->reproducible && dev != -1) {
fprintf(ctx->fout, "address of net dev #%" PRIu8 ": 0x%x\n", dev_num, dev);
}
}
@ -4020,6 +4100,7 @@ run_test(struct shell_ctx *ctx) {
dup2(fileno(ctx->fin), STDIN_FILENO);
fclose(ctx->fin);
}
ic_init_custom_malloc(NULL, NULL, NULL);
// ic_style_def("ic-prompt","ansi-default");
ic_enable_color(0);
ic_set_prompt_marker(NULL, NULL);
@ -4027,14 +4108,14 @@ run_test(struct shell_ctx *ctx) {
ic_enable_beep(0);
pthread_mutex_lock(&ctx->cmd_mutex);
int is_tty = isatty(fileno(ctx->fin));
int is_tty = isatty(fileno(stdin));
char **argv = (char**)calloc(sizeof(char*), (MAX_COMMAND_ARGS + 1));
ic_set_default_completer(&completer, NULL);
ic_set_default_completer(completer, NULL);
ic_set_default_highlighter(highlighter, NULL);
ic_enable_auto_tab(1);
sprintf(prompt_line, "%s", last_dir);
char *line;
while((line = ic_readline(prompt_line)) || !feof(stdin)) {
while ((line = ic_readline(prompt_line)) || !feof(stdin)) {
if (!is_tty) {
prompt(ctx);
fprintf(ctx->fout, "%s\n", line ? line : "");

View File

@ -66,7 +66,7 @@ terminate_protection: 1
keyboard_mode: 0
captionEncoding: 0
exec_params: (null)
wnd_caption: hi_there
wnd_caption:
wnd_clientbox (ltwh): 5 24 291 172
priority: 0
in_schedule: prev (2), next (2)

View File

@ -44,10 +44,8 @@ status: ok
status: ok
/> net_get_dev 0
status: ok
address of net dev #0: 0x80d12d8
/> net_get_dev 1
status: ok
address of net dev #1: 0x2aa8b100
/> net_get_packet_tx_count 0
status: ok
packet tx count of net dev #0: 0

View File

@ -67,7 +67,7 @@ terminate_protection: 1
keyboard_mode: 0
captionEncoding: 0
exec_params: (null)
wnd_caption: hi_there
wnd_caption:
wnd_clientbox (ltwh): 5 24 291 172
priority: 0
in_schedule: prev (2), next (2)

View File

@ -67,7 +67,7 @@ terminate_protection: 1
keyboard_mode: 0
captionEncoding: 0
exec_params: (null)
wnd_caption: hi_there
wnd_caption:
wnd_clientbox (ltwh): 5 24 291 172
priority: 0
in_schedule: prev (2), next (2)

View File

@ -152,7 +152,7 @@ pubsym img_background
pubsym mem_BACKGROUND
pubsym sys_background
pubsym REDRAW_BACKGROUND, 'kos_redraw_background'
pubsym new_sys_threads, 'kos_new_sys_threads', no_mangle
pubsym new_sys_threads, '_kos_new_sys_threads', no_mangle
pubsym osloop, 'kos_osloop', no_mangle
pubsym set_mouse_data, 'kos_set_mouse_data', 20
pubsym scheduler_current, 'kos_scheduler_current'
@ -959,14 +959,6 @@ init_sys_v86:
usb_init:
fdc_init:
mtrr_validate:
; sys32.inc
;terminate:
;protect_from_terminate:
;unprotect_from_terminate:
;lock_application_table:
;unlock_application_table:
;sys_resize_app_memory:
;request_terminate:
v86_exc_c:
except_7:
ReadCDWRetr:
@ -1032,11 +1024,15 @@ macro pew x {inclu#de `x}
macro org x {}
macro format [x] {}
UMKA_RUNNIGS_NEVER = 0
UMKA_RUNNIGS_NOT_YET = 1
UMKA_RUNNIGS_YES = 2
bios32_entry equ bios32_entry_pew
tmp_page_tabs equ tmp_page_tabs_pew
macro jmp target {
if target eq osloop
cmp [umka.running], 1
cmp [umka.running], UMKA_RUNNIGS_YES
jz osloop
ret
else

350
umka.h
View File

@ -20,6 +20,8 @@
#include <time.h>
#define UMKA_PATH_MAX 4096
#define UMKA_DEFAULT_THREAD_STACK_SIZE 0x10000
// TODO: Cleanup
#ifndef _WIN32
#include <signal.h> // for irq0: siginfo_t
@ -614,144 +616,6 @@ struct ret_create_event {
uint32_t uid;
};
static inline struct ret_create_event
kos_create_event(void *data, uint32_t flags) {
struct ret_create_event ret;
__asm__ __inline__ __volatile__ (
"push ebx esi edi ebp;"
"call _kos_create_event;"
"pop ebp edi esi ebx"
: "=a"(ret.event),
"=d"(ret.uid)
: "S"(data),
"c"(flags)
: "memory", "cc");
return ret;
}
static inline void*
kos_destroy_event(void *event, uint32_t uid) {
void *ret;
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_destroy_event;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
: "=a"(ret)
: "a"(event),
"b"(uid)
: "memory", "cc");
return ret;
}
static inline void
kos_wait_event(void *event, uint32_t uid) {
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_wait_event;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
:
: "a"(event),
"b"(uid)
: "memory", "cc");
}
typedef uint32_t (*wait_test_t)(void);
static inline void *
kos_wait_events(wait_test_t wait_test, void *wait_param) {
void *res;
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_wait_events;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
: "=a"(res)
: "c"(wait_param),
"d"(wait_test)
: "memory", "cc");
return res;
}
static inline int32_t
umka_fs_execute(const char *filename) {
// edx Flags
// ecx Commandline
// ebx Absolute file path
// eax String length
int32_t result;
__asm__ __inline__ __volatile__ (
"push ebp;"
"call kos_fs_execute;"
"pop ebp"
: "=a"(result)
: "a"(strlen(filename)),
"b"(filename),
"c"(NULL),
"d"(0)
: "memory");
return result;
}
static inline size_t
umka_new_sys_threads(uint32_t flags, void (*entry)(void), void *stack) {
size_t tid;
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"call kos_new_sys_threads;"
"pop edi;"
"pop esi;"
"pop ebx"
: "=a"(tid)
: "b"(flags),
"c"(entry),
"d"(stack)
: "memory", "cc");
return tid;
}
static inline void
kos_enable_acpi(void) {
__asm__ __inline__ __volatile__ (
"pusha;"
"call enable_acpi;"
"popa"
:
:
: "memory", "cc");
}
static inline void
kos_acpi_call_name(void *ctx, const char *name) {
__asm__ __inline__ __volatile__ (
"pusha;"
"push %[name];"
"push %[ctx];"
"call acpi.call_name;"
"popa"
:
: [ctx] "r"(ctx), [name] "r"(name)
: "memory", "cc");
}
#define KOS_ACPI_NODE_Uninitialized 1
#define KOS_ACPI_NODE_Integer 2
#define KOS_ACPI_NODE_String 3
@ -1158,6 +1022,160 @@ umka_i40(pushad_t *regs) {
&regs->ebx);
}
static inline struct ret_create_event
kos_create_event(void *data, uint32_t flags) {
struct ret_create_event ret;
__asm__ __inline__ __volatile__ (
"push ebx esi edi ebp;"
"call _kos_create_event;"
"pop ebp edi esi ebx"
: "=a"(ret.event),
"=d"(ret.uid)
: "S"(data),
"c"(flags)
: "memory", "cc");
return ret;
}
static inline void*
kos_destroy_event(void *event, uint32_t uid) {
void *ret;
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_destroy_event;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
: "=a"(ret)
: "a"(event),
"b"(uid)
: "memory", "cc");
return ret;
}
static inline void
kos_wait_event(void *event, uint32_t uid) {
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_wait_event;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
:
: "a"(event),
"b"(uid)
: "memory", "cc");
}
typedef uint32_t (*wait_test_t)(void);
static inline void *
kos_wait_events(wait_test_t wait_test, void *wait_param) {
void *res;
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_wait_events;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
: "=a"(res)
: "c"(wait_param),
"d"(wait_test)
: "memory", "cc");
return res;
}
static inline int32_t
umka_fs_execute(const char *filename) {
// edx Flags
// ecx Commandline
// ebx Absolute file path
// eax String length
int32_t result;
__asm__ __inline__ __volatile__ (
"push ebp;"
"call kos_fs_execute;"
"pop ebp"
: "=a"(result)
: "a"(strlen(filename)),
"b"(filename),
"c"(NULL),
"d"(0)
: "memory");
return result;
}
typedef void (*kos_thread_t)(void);
static inline size_t
kos_new_sys_threads(uint32_t flags, kos_thread_t entry, void *stack_top) {
size_t tid;
__asm__ __inline__ __volatile__ (
"push ebx;"
"push esi;"
"push edi;"
"push ebp;"
"call _kos_new_sys_threads;"
"pop ebp;"
"pop edi;"
"pop esi;"
"pop ebx"
: "=a"(tid)
: "b"(flags),
"c"(entry),
"d"(stack_top)
: "memory", "cc");
return tid;
}
static inline size_t
umka_new_sys_threads(uint32_t flags, void (*entry)(void *), void *stack_top,
void *arg) {
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;
*(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
return tid;
}
static inline void
kos_enable_acpi(void) {
__asm__ __inline__ __volatile__ (
"pusha;"
"call enable_acpi;"
"popa"
:
:
: "memory", "cc");
}
static inline void
kos_acpi_call_name(void *ctx, const char *name) {
__asm__ __inline__ __volatile__ (
"pusha;"
"push %[name];"
"push %[ctx];"
"call acpi.call_name;"
"popa"
:
: [ctx] "r"(ctx), [name] "r"(name)
: "memory", "cc");
}
static inline void
umka_sys_draw_window(size_t x, size_t xsize, size_t y, size_t ysize,
uint32_t color, int has_caption, int client_relative,
@ -2382,60 +2400,4 @@ umka_set_keyboard_data(uint32_t scancode) {
: "eax", "edx", "memory", "cc");
}
#define CMD_BUF_LEN 0x10
enum {
UMKA_CMD_NONE,
UMKA_CMD_SET_MOUSE_DATA,
UMKA_CMD_SYS_PROCESS_INFO,
UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN,
UMKA_CMD_SYS_LFN,
};
enum {
UMKA_CMD_STATUS_EMPTY,
UMKA_CMD_STATUS_READY,
UMKA_CMD_STATUS_DONE,
};
struct cmd_set_mouse_data {
uint32_t btn_state;
int32_t xmoving;
int32_t ymoving;
int32_t vscroll;
int32_t hscroll;
};
struct cmd_sys_lfn {
f70or80_t f70or80;
f7080s1arg_t *bufptr;
f7080ret_t *r;
};
struct cmd_ret_sys_lfn {
f7080ret_t status;
};
struct cmd_sys_process_info {
int32_t pid;
void *param;
};
struct cmd_ret_sys_get_mouse_pos_screen {
struct point16s pos;
};
struct umka_cmd {
atomic_int status;
uint32_t type;
union {
struct cmd_set_mouse_data set_mouse_data;
struct cmd_sys_lfn sys_lfn;
} arg;
union {
struct cmd_ret_sys_get_mouse_pos_screen sys_get_mouse_pos_screen;
struct cmd_ret_sys_lfn sys_lfn;
} ret;
};
#endif // UMKA_H_INCLUDED

View File

@ -33,7 +33,6 @@
#define HIST_FILE_BASENAME ".umka_os.history"
#define THREAD_STACK_SIZE 0x100000
#define APP_MAX_MEM_SIZE 0x1000000
#define UMKA_LDR_BASE ((void*)0x1000000)
@ -48,19 +47,6 @@ struct umka_os_ctx *os;
char history_filename[PATH_MAX];
static void
completer(ic_completion_env_t *cenv, const char *prefix) {
(void)cenv;
(void)prefix;
}
static void
highlighter(ic_highlight_env_t *henv, const char *input, void *arg) {
(void)henv;
(void)input;
(void)arg;
}
static int
hw_int_mouse(void *arg) {
(void)arg;
@ -88,25 +74,20 @@ build_history_filename(void) {
sprintf(history_filename, "%s/%s", dir_name, HIST_FILE_BASENAME);
}
void
umka_thread_net_drv(void);
struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000},
.it_interval = {.tv_sec = 0, .tv_usec = 10000}};
typedef void (*kos_thread_t)(void);
static void
thread_start(int is_kernel, void (*entry)(void), size_t stack_size) {
fprintf(stderr, "### thread_start: %p\n", (void*)(uintptr_t)entry);
thread_start(int is_kernel, kos_thread_t entry, size_t stack_size) {
fprintf(stderr, "[os] starting thread: %p\n", (void*)(uintptr_t)entry);
uint8_t *stack = malloc(stack_size);
umka_new_sys_threads(is_kernel, entry, stack + stack_size);
kos_new_sys_threads(is_kernel, entry, stack + stack_size);
}
static void
dump_procs(void) {
for (int i = 0; i < KOS_NR_SCHED_QUEUES; i++) {
fprintf(stderr, "sched queue #%i:", i);
fprintf(stderr, "[os] sched queue #%i:", i);
appdata_t *p_begin = kos_scheduler_current[i];
appdata_t *p = p_begin;
do {
@ -119,7 +100,7 @@ dump_procs(void) {
int
load_app_host(const char *fname, struct app_hdr *app) {
FILE *f = fopen(fname, "r");
FILE *f = fopen(fname, "rb");
if (!f) {
fprintf(stderr, "[!] can't open app file: %s", fname);
exit(1);
@ -128,7 +109,7 @@ load_app_host(const char *fname, struct app_hdr *app) {
fclose(f);
kos_thread_t start = (kos_thread_t)(app->menuet.start);
thread_start(0, start, THREAD_STACK_SIZE);
thread_start(0, start, UMKA_DEFAULT_THREAD_STACK_SIZE);
return 0;
}
@ -222,27 +203,10 @@ umka_display(void *arg) {
return NULL;
}
static uint32_t
umka_run_cmd_wait_test(void /* struct appdata * with wait_param is in ebx */) {
appdata_t *app;
__asm__ __volatile__ __inline__ ("":"=b"(app)::);
struct umka_cmd *cmd = (struct umka_cmd*)app->wait_param;
return (uint32_t)(atomic_load_explicit(&cmd->status, memory_order_acquire) == UMKA_CMD_STATUS_READY);
}
static void
umka_thread_cmd_runner(void) {
umka_sti();
while (1) {
kos_wait_events(umka_run_cmd_wait_test, umka_cmd_buf);
umka_run_cmd_sync(os->shell);
}
}
static void *
umka_monitor(void *arg) {
(void)arg;
run_test(os->shell);
struct shell_ctx *sh = arg;
run_test(sh);
exit(0);
}
@ -263,7 +227,7 @@ int
main(int argc, char *argv[]) {
(void)argc;
const char *usage = "umka_os [-i <infile>] [-o <outfile>]"
" [-b <boardlog>] [\n";
" [-b <boardlog>] [-s <startupfile>]\n";
if (coverage) {
trace_begin();
}
@ -273,9 +237,6 @@ main(int argc, char *argv[]) {
umka_sti();
build_history_filename();
ic_set_default_completer(&completer, NULL);
ic_set_default_highlighter(highlighter, NULL);
ic_enable_auto_tab(1);
const char *startupfile = NULL;
const char *infile = NULL;
@ -315,7 +276,7 @@ main(int argc, char *argv[]) {
}
if (startupfile) {
fstartup = fopen(startupfile, "r");
fstartup = fopen(startupfile, "rb");
if (!fstartup) {
fprintf(stderr, "[!] can't open file for reading: %s\n",
startupfile);
@ -323,21 +284,21 @@ main(int argc, char *argv[]) {
}
}
if (infile) {
fin = fopen(infile, "r");
fin = fopen(infile, "rb");
if (!fin) {
fprintf(stderr, "[!] can't open file for reading: %s\n", infile);
exit(1);
}
}
if (outfile) {
fout = fopen(outfile, "w");
fout = fopen(outfile, "wb");
if (!fout) {
fprintf(stderr, "[!] can't open file for writing: %s\n", outfile);
exit(1);
}
}
if (boardlogfile) {
fboardlog = fopen(boardlogfile, "w");
fboardlog = fopen(boardlogfile, "wb");
if (!fboardlog) {
fprintf(stderr, "[!] can't open file for writing: %s\n",
boardlogfile);
@ -399,7 +360,7 @@ main(int argc, char *argv[]) {
run_test(os->shell);
os->shell->fin = fin;
umka_stack_init();
clearerr(stdin); // reset feof
// load_app("/rd/1/loader");
@ -446,8 +407,7 @@ main(int argc, char *argv[]) {
kos_attach_int_handler(UMKA_IRQ_MOUSE, hw_int_mouse, NULL);
thread_start(1, umka_thread_board, THREAD_STACK_SIZE);
thread_start(1, umka_thread_cmd_runner, THREAD_STACK_SIZE);
thread_start(1, umka_thread_board, UMKA_DEFAULT_THREAD_STACK_SIZE);
load_app_host("../apps/loader", UMKA_LDR_BASE);
// load_app_host("../apps/justawindow", KOS_APP_BASE);
load_app_host("../apps/asciivju", KOS_APP_BASE);
@ -455,7 +415,7 @@ main(int argc, char *argv[]) {
dump_procs();
pthread_t thread_monitor;
pthread_create(&thread_monitor, NULL, umka_monitor, NULL);
pthread_create(&thread_monitor, NULL, umka_monitor, os->shell);
if (show_display) {
pthread_t thread_display;

View File

@ -2,4 +2,5 @@ umka_set_boot_params --bpp 32 --x_res 800 --y_res 600
umka_boot
ramdisk_init ../img/kolibri.raw
set_skin /sys/DEFAULT.SKN
disk_add ../img/xfs_samehash_s05k.raw hd0 -c 0
disk_add ../img/xfs_samehash_s05k.raw hd0 -c 0
stack_init

View File

@ -35,7 +35,7 @@ struct umka_shell_ctx *
umka_shell_init(int reproducible, FILE *fin) {
struct umka_shell_ctx *ctx = malloc(sizeof(struct umka_shell_ctx));
ctx->umka = umka_init(UMKA_RUNNING_NEVER);
ctx->io = io_init(NULL);
ctx->io = io_init(&ctx->umka->running);
ctx->shell = shell_init(reproducible, history_filename, ctx->umka, ctx->io,
fin);
return ctx;

View File

@ -18,13 +18,66 @@
#define IOT_QUEUE_DEPTH 1
enum {
IOT_CMD_STATUS_EMPTY,
IOT_CMD_STATUS_READY,
IOT_CMD_STATUS_DONE,
};
enum {
IOT_CMD_READ,
IOT_CMD_WRITE,
};
struct iot_cmd_read_arg {
int fd;
void *buf;
size_t count;
};
struct iot_cmd_read_ret {
ssize_t val;
};
union iot_cmd_read {
struct iot_cmd_read_arg arg;
struct iot_cmd_read_ret ret;
};
struct iot_cmd_write_arg {
int fd;
void *buf;
size_t count;
};
struct iot_cmd_write_ret {
ssize_t val;
};
union iot_cmd_write {
struct iot_cmd_write_arg arg;
struct iot_cmd_write_ret ret;
};
struct iot_cmd {
pthread_cond_t iot_cond;
pthread_mutex_t iot_mutex;
pthread_mutex_t mutex;
int type;
atomic_int status;
union {
union iot_cmd_read read;
union iot_cmd_write write;
};
};
struct iot_cmd iot_cmd_buf[IOT_QUEUE_DEPTH];
static void *
thread_io(void *arg) {
(void)arg;
for (size_t i = 0; i < IOT_QUEUE_DEPTH; i++) {
iot_cmd_buf[i].status = UMKA_CMD_STATUS_EMPTY;
iot_cmd_buf[i].status = IOT_CMD_STATUS_EMPTY;
iot_cmd_buf[i].type = 0;
pthread_cond_init(&iot_cmd_buf[i].iot_cond, NULL);
pthread_mutex_init(&iot_cmd_buf[i].iot_mutex, NULL);
@ -38,11 +91,11 @@ thread_io(void *arg) {
pthread_cond_wait(&cmd->iot_cond, &cmd->iot_mutex);
// status must be ready
switch (cmd->type) {
case IOT_CMD_TYPE_READ:
case IOT_CMD_READ:
ret = read(cmd->read.arg.fd, cmd->read.arg.buf, cmd->read.arg.count);
cmd->read.ret.val = ret;
break;
case IOT_CMD_TYPE_WRITE:
case IOT_CMD_WRITE:
cmd->read.ret.val = write(cmd->read.arg.fd, cmd->read.arg.buf,
cmd->read.arg.count);
break;
@ -50,7 +103,7 @@ thread_io(void *arg) {
break;
}
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_DONE, memory_order_release);
atomic_store_explicit(&cmd->status, IOT_CMD_STATUS_DONE, memory_order_release);
}
return NULL;
@ -71,7 +124,7 @@ io_async_complete_wait_test(void) {
// __asm__ __volatile__ ("":"=b"(app)::);
// struct io_uring_queue *q = app->wait_param;
int status = atomic_load_explicit(&iot_cmd_buf[0].status, memory_order_acquire);
return status == UMKA_CMD_STATUS_DONE;
return status == IOT_CMD_STATUS_DONE;
}
ssize_t
@ -81,17 +134,18 @@ io_async_read(int fd, void *buf, size_t count, void *arg) {
kos_wait_events(io_async_submit_wait_test, NULL);
// status must be empty
struct iot_cmd *cmd = iot_cmd_buf;
cmd->type = IOT_CMD_READ;
cmd->read.arg.fd = fd;
cmd->read.arg.buf = buf;
cmd->read.arg.count = count;
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_READY, memory_order_release);
atomic_store_explicit(&cmd->status, IOT_CMD_STATUS_READY, memory_order_release);
pthread_cond_signal(&cmd->iot_cond);
kos_wait_events(io_async_complete_wait_test, NULL);
ssize_t res = cmd->read.ret.val;
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_EMPTY, memory_order_release);
atomic_store_explicit(&cmd->status, IOT_CMD_STATUS_EMPTY, memory_order_release);
pthread_mutex_unlock(&cmd->mutex);
return res;
@ -124,7 +178,7 @@ io_close(struct umka_io *io) {
ssize_t
io_read(int fd, void *buf, size_t count, const struct umka_io *io) {
ssize_t res;
if (!io->running || !*io->running) {
if (*io->running < UMKA_RUNNING_YES) {
res = read(fd, buf, count);
} else {
res = io_async_read(fd, buf, count, NULL);
@ -135,7 +189,7 @@ io_read(int fd, void *buf, size_t count, const struct umka_io *io) {
ssize_t
io_write(int fd, const void *buf, size_t count, const struct umka_io *io) {
ssize_t res;
if (!io->running || !*io->running) {
if (*io->running < UMKA_RUNNING_YES) {
res = write(fd, buf, count);
} else {
res = io_async_write(fd, buf, count, NULL);

View File

@ -23,53 +23,6 @@ struct umka_io {
pthread_t iot;
};
struct iot_cmd_read_arg {
int fd;
void *buf;
size_t count;
};
struct iot_cmd_read_ret {
ssize_t val;
};
union iot_cmd_read {
struct iot_cmd_read_arg arg;
struct iot_cmd_read_ret ret;
};
struct iot_cmd_write_arg {
int fd;
void *buf;
size_t count;
};
struct iot_cmd_write_ret {
ssize_t val;
};
union iot_cmd_write {
struct iot_cmd_write_arg arg;
struct iot_cmd_write_ret ret;
};
enum {
IOT_CMD_TYPE_READ,
IOT_CMD_TYPE_WRITE,
};
struct iot_cmd {
pthread_cond_t iot_cond;
pthread_mutex_t iot_mutex;
pthread_mutex_t mutex;
atomic_int status;
int type;
union {
union iot_cmd_read read;
union iot_cmd_write write;
};
};
struct umka_io *
io_init(atomic_int *running);

View File

@ -25,8 +25,6 @@ struct devices_dat_entry {
uint32_t pad2;
};
struct umka_cmd umka_cmd_buf[CMD_BUF_LEN];
static STDCALL void*
dump_devices_dat_iter(struct pci_dev *node, void *arg) {
FILE *f = arg;

View File

@ -15,8 +15,6 @@
extern atomic_int umka_irq_number;
extern struct umka_cmd umka_cmd_buf[CMD_BUF_LEN];
void
dump_devices_dat(const char *filename);