diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-11 16:50:13 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-11 16:50:13 +0100 |
commit | 64b9108a58d3483e9b63511c4cf74b12dceeb0f6 (patch) | |
tree | 7a3352828a318bcf0126f50ac3d31c8b16540703 /src/kernel | |
parent | 9b9ef5a2c0ec8e66c7da24c4229d89a90a10e914 (diff) | |
download | kogata-64b9108a58d3483e9b63511c4cf74b12dceeb0f6.tar.gz kogata-64b9108a58d3483e9b63511c4cf74b12dceeb0f6.zip |
Change thread waiting technology. Slower but does not do crappy things like malloc at impractical places.
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/core/idt.c | 2 | ||||
-rw-r--r-- | src/kernel/core/kmalloc.c | 6 | ||||
-rw-r--r-- | src/kernel/core/paging.c | 8 | ||||
-rw-r--r-- | src/kernel/core/thread.c | 68 | ||||
-rw-r--r-- | src/kernel/include/thread.h | 4 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 80 |
6 files changed, 81 insertions, 87 deletions
diff --git a/src/kernel/core/idt.c b/src/kernel/core/idt.c index f3dd63b..d963b4d 100644 --- a/src/kernel/core/idt.c +++ b/src/kernel/core/idt.c @@ -91,7 +91,7 @@ static isr_handler_t ex_handlers[32] = {0}; /* Called in interrupt.s when an exception fires (interrupt 0 to 31) */ void idt_ex_handler(registers_t *regs) { - dbg_printf("Ex handler: %d\n", regs->int_no); + dbg_printf("ex%d.", regs->int_no); if (ex_handlers[regs->int_no] != 0) { ex_handlers[regs->int_no](regs); } else { diff --git a/src/kernel/core/kmalloc.c b/src/kernel/core/kmalloc.c index c977e54..cc20487 100644 --- a/src/kernel/core/kmalloc.c +++ b/src/kernel/core/kmalloc.c @@ -16,7 +16,10 @@ static void* page_alloc_fun_for_kmalloc(size_t bytes) { for (void* i = addr; i < addr + bytes; i += PAGE_SIZE) { int f = frame_alloc(1); if (f == 0) goto failure; - if (!pd_map_page(i, f, true)) goto failure; + if (!pd_map_page(i, f, true)) { + frame_free(f, 1); + goto failure; + } } return addr; @@ -29,6 +32,7 @@ failure: frame_free(f, 1); } } + region_free(addr); return 0; } diff --git a/src/kernel/core/paging.c b/src/kernel/core/paging.c index 03a973f..cefb8c3 100644 --- a/src/kernel/core/paging.c +++ b/src/kernel/core/paging.c @@ -209,13 +209,7 @@ bool pd_map_page(void* vaddr, uint32_t frame_id, bool rw) { mutex_lock(&pdd->mutex); if (!(pd->page[pt] & PTE_PRESENT)) { - uint32_t new_pt_frame; - int tries = 0; - while ((new_pt_frame = frame_alloc(1)) == 0 && (tries++) < 3) { - mutex_unlock(&pdd->mutex); - free_some_memory(); - mutex_lock(&pdd->mutex); - } + uint32_t new_pt_frame = frame_alloc(1); if (new_pt_frame == 0) { mutex_unlock(&pdd->mutex); return false; diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index ed2c185..19ad6c8 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -18,7 +18,7 @@ void resume_context(saved_context_t *ctx); thread_t *current_thread = 0; -static hashtbl_t *waiters = 0; // threads waiting on a ressource +static thread_t *waiters = 0; // ====================== // // THE PROGRAMMABLE TIMER // @@ -235,9 +235,6 @@ void threading_irq0_handler() { } } void threading_setup(entry_t cont, void* arg) { - waiters = create_hashtbl(id_key_eq_fun, id_hash_fun, 0); - ASSERT(waiters != 0); - set_pit_frequency(TASK_SWITCH_FREQUENCY); idt_set_irq_handler(IRQ0, &irq0_handler); @@ -286,34 +283,20 @@ bool wait_on_many(void** x, size_t n) { int st = enter_critical(CL_NOINT); - // ---- Check we can wait on all the requested objects - bool ok = true; - for (size_t i = 0; ok && i < n; i++) { - void* prev_th = hashtbl_find(waiters, x[i]); - if (prev_th == 0) { - bool add_ok = hashtbl_add(waiters, x[i], (void*)1); - if (!add_ok) { - ok = false; - } - } else if (prev_th != (void*)1) { - ok = false; - break; - } - } - if (!ok) { - exit_critical(st); - return false; - } - // ---- Set ourselves as the waiting thread for all the requested objets - dbg_printf("Wait on many: "); + dbg_printf("Wait on many:"); for (size_t i = 0; i < n; i++) { - ASSERT(hashtbl_change(waiters, x[i], current_thread)); - dbg_printf("0x%p (0x%p) ", x[i], hashtbl_find(waiters, x[i])); + dbg_printf(" 0x%p", x[i]); } dbg_printf("\n"); + current_thread->waiting_on = x; + current_thread->n_waiting_on = n; + + current_thread->next_waiter = waiters; + waiters = current_thread; + // ---- Go to sleep current_thread->state = T_STATE_PAUSED; @@ -321,8 +304,15 @@ bool wait_on_many(void** x, size_t n) { // ---- Remove ourselves from the list - for (size_t i = 0; i < n; i++) { - ASSERT(hashtbl_change(waiters, x[i], (void*)1)); + current_thread->waiting_on = 0; + current_thread->n_waiting_on = 0; + + if (waiters == current_thread) { + waiters = current_thread->next_waiter; + } else { + for (thread_t *w = waiters; w->next_waiter != 0; w = w->next_waiter) { + if (w->next_waiter == current_thread) w->next_waiter = current_thread->next_waiter; + } } exit_critical(st); @@ -374,24 +364,26 @@ void exit() { } bool resume_on(void* x) { - - thread_t *thread; - bool ret = false; int st = enter_critical(CL_NOINT); - thread = hashtbl_find(waiters, x); + dbg_printf("Resume on 0x%p:", x); - dbg_printf("Resume on 0x%p : 0x%p\n", x, thread); + for (thread_t *t = waiters; t != 0; t = t->next_waiter) { + for (int i = 0; i < t->n_waiting_on; i++) { + if (t->waiting_on[i] == x) { + dbg_printf(" 0x%p", t); - if (thread != 0 && thread != (void*)1) { - if (thread->state == T_STATE_PAUSED) { - thread->state = T_STATE_RUNNING; + if (t->state == T_STATE_PAUSED) { + t->state = T_STATE_RUNNING; - enqueue_thread(thread, false); + enqueue_thread(t, false); - ret = true; + ret = true; + } + break; + } } } diff --git a/src/kernel/include/thread.h b/src/kernel/include/thread.h index 698c4c6..fbcc178 100644 --- a/src/kernel/include/thread.h +++ b/src/kernel/include/thread.h @@ -36,6 +36,10 @@ typedef struct thread { struct thread *next_in_queue; struct thread *next_in_proc; + void** waiting_on; + int n_waiting_on; + struct thread *next_waiter; + bool must_exit; } thread_t; diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c index 606ab3f..350262c 100644 --- a/src/kernel/user/syscall.c +++ b/src/kernel/user/syscall.c @@ -16,7 +16,7 @@ typedef uint32_t (*syscall_handler_t)(sc_args_t); static syscall_handler_t sc_handlers[SC_MAX] = { 0 }; -static char* sc_copy_string(const char* addr, size_t slen) { +char* sc_copy_string(const char* addr, size_t slen) { probe_for_read(addr, slen); char* buf = malloc(slen+1); @@ -28,7 +28,7 @@ static char* sc_copy_string(const char* addr, size_t slen) { return buf; } -static char* sc_copy_string_x(uint32_t s, uint32_t slen) { +char* sc_copy_string_x(uint32_t s, uint32_t slen) { return sc_copy_string((const char*)s, slen); } @@ -38,7 +38,7 @@ static char* sc_copy_string_x(uint32_t s, uint32_t slen) { // ---- Related to the current process's execution -static uint32_t exit_sc(sc_args_t args) { +uint32_t exit_sc(sc_args_t args) { dbg_printf("Proc %d exit with code %d\n", current_process()->pid, args.a); current_process_exit(PS_FINISHED, args.a); @@ -46,17 +46,17 @@ static uint32_t exit_sc(sc_args_t args) { return 0; } -static uint32_t yield_sc(sc_args_t args) { +uint32_t yield_sc(sc_args_t args) { yield(); return 0; } -static uint32_t usleep_sc(sc_args_t args) { +uint32_t usleep_sc(sc_args_t args) { usleep(args.a); return 0; } -static uint32_t dbg_print_sc(sc_args_t args) { +uint32_t dbg_print_sc(sc_args_t args) { char* msg = sc_copy_string_x(args.a, args.b); if (msg == 0) return -1; @@ -70,22 +70,22 @@ static uint32_t dbg_print_sc(sc_args_t args) { return 0; } -static uint32_t new_thread_sc(sc_args_t args) { +uint32_t new_thread_sc(sc_args_t args) { return process_new_thread(current_process(), (proc_entry_t)args.a, (void*)args.b); } -static uint32_t exit_thread_sc(sc_args_t args) { +uint32_t exit_thread_sc(sc_args_t args) { exit(); return 0; } // ---- Memory management related -static uint32_t mmap_sc(sc_args_t args) { +uint32_t mmap_sc(sc_args_t args) { return mmap(current_process(), (void*)args.a, args.b, args.c); } -static uint32_t mmap_file_sc(sc_args_t args) { +uint32_t mmap_file_sc(sc_args_t args) { int fd = args.a; fs_handle_t *h = proc_read_fd(current_process(), fd); if (h == 0) return false; @@ -93,17 +93,17 @@ static uint32_t mmap_file_sc(sc_args_t args) { return mmap_file(current_process(), h, args.b, (void*)args.c, args.d, args.e); } -static uint32_t mchmap_sc(sc_args_t args) { +uint32_t mchmap_sc(sc_args_t args) { return mchmap(current_process(), (void*)args.a, args.b); } -static uint32_t munmap_sc(sc_args_t args) { +uint32_t munmap_sc(sc_args_t args) { return munmap(current_process(), (void*)args.a); } // ---- Accessing the VFS - filesystems -static uint32_t create_sc(sc_args_t args) { +uint32_t create_sc(sc_args_t args) { bool ret = false; char* fn = sc_copy_string_x(args.a, args.b); @@ -125,7 +125,7 @@ end_create: return ret; } -static uint32_t delete_sc(sc_args_t args) { +uint32_t delete_sc(sc_args_t args) { bool ret = false; char* fn = sc_copy_string_x(args.a, args.b); @@ -147,7 +147,7 @@ end_del: return ret; } -static uint32_t move_sc(sc_args_t args) { +uint32_t move_sc(sc_args_t args) { bool ret = false; char *fn_a = sc_copy_string_x(args.a, args.b), @@ -177,7 +177,7 @@ end_move: return ret; } -static uint32_t stat_sc(sc_args_t args) { +uint32_t stat_sc(sc_args_t args) { bool ret = false; char* fn = sc_copy_string_x(args.a, args.b); @@ -202,7 +202,7 @@ end_stat: // ---- Accessing the VFS - files -static uint32_t open_sc(sc_args_t args) { +uint32_t open_sc(sc_args_t args) { int ret = 0; char* fn = sc_copy_string_x(args.a, args.b); @@ -228,12 +228,12 @@ end_open: return ret; } -static uint32_t close_sc(sc_args_t args) { +uint32_t close_sc(sc_args_t args) { proc_close_fd(current_process(), args.a); return 0; } -static uint32_t read_sc(sc_args_t args) { +uint32_t read_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return 0; @@ -243,7 +243,7 @@ static uint32_t read_sc(sc_args_t args) { return file_read(h, args.b, len, data); } -static uint32_t write_sc(sc_args_t args) { +uint32_t write_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return 0; @@ -253,7 +253,7 @@ static uint32_t write_sc(sc_args_t args) { return file_write(h, args.b, len, data); } -static uint32_t readdir_sc(sc_args_t args) { +uint32_t readdir_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return false; @@ -262,7 +262,7 @@ static uint32_t readdir_sc(sc_args_t args) { return file_readdir(h, args.b, o); } -static uint32_t stat_open_sc(sc_args_t args) { +uint32_t stat_open_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return false; @@ -271,7 +271,7 @@ static uint32_t stat_open_sc(sc_args_t args) { return file_stat(h, o); } -static uint32_t ioctl_sc(sc_args_t args) { +uint32_t ioctl_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return -1; @@ -280,7 +280,7 @@ static uint32_t ioctl_sc(sc_args_t args) { return file_ioctl(h, args.b, data); } -static uint32_t fctl_sc(sc_args_t args) { +uint32_t fctl_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return 0; @@ -297,7 +297,7 @@ static uint32_t fctl_sc(sc_args_t args) { } } -static uint32_t select_sc(sc_args_t args) { +uint32_t select_sc(sc_args_t args) { sel_fd_t *fds = (sel_fd_t*)args.a; size_t n = args.b; int timeout = args.c; @@ -351,7 +351,7 @@ static uint32_t select_sc(sc_args_t args) { // ---- IPC -static uint32_t make_channel_sc(sc_args_t args) { +uint32_t make_channel_sc(sc_args_t args) { // messy messy messy bool blocking = (args.a != 0); @@ -389,7 +389,7 @@ error: return false; } -static uint32_t make_shm_sc(sc_args_t args) { +uint32_t make_shm_sc(sc_args_t args) { fs_handle_t *h = make_shm(args.a); if (h == 0) return 0; @@ -402,7 +402,7 @@ static uint32_t make_shm_sc(sc_args_t args) { return fd; } -static uint32_t gen_token_sc(sc_args_t args) { +uint32_t gen_token_sc(sc_args_t args) { fs_handle_t *h = proc_read_fd(current_process(), args.a); if (h == 0) return false; @@ -412,7 +412,7 @@ static uint32_t gen_token_sc(sc_args_t args) { return gen_token_for(h, tok); } -static uint32_t use_token_sc(sc_args_t args) { +uint32_t use_token_sc(sc_args_t args) { token_t *tok = (token_t*)args.a; probe_for_read(tok, sizeof(token_t)); @@ -430,7 +430,7 @@ static uint32_t use_token_sc(sc_args_t args) { // ---- Managing file systems -static uint32_t make_fs_sc(sc_args_t args) { +uint32_t make_fs_sc(sc_args_t args) { sc_make_fs_args_t *a = (sc_make_fs_args_t*)args.a; probe_for_read(a, sizeof(sc_make_fs_args_t)); @@ -477,7 +477,7 @@ end_mk_fs: return ok; } -static uint32_t fs_add_src_sc(sc_args_t args) { +uint32_t fs_add_src_sc(sc_args_t args) { bool ok = false; char* opts = 0; @@ -503,7 +503,7 @@ end_add_src: return ok; } -static uint32_t fs_subfs_sc(sc_args_t args) { +uint32_t fs_subfs_sc(sc_args_t args) { sc_subfs_args_t *a = (sc_subfs_args_t*)args.a; probe_for_read(a, sizeof(sc_subfs_args_t)); @@ -547,7 +547,7 @@ end_subfs: return ok; } -static uint32_t rm_fs_sc(sc_args_t args) { +uint32_t rm_fs_sc(sc_args_t args) { char* fs_name = sc_copy_string_x(args.a, args.b); if (fs_name == 0) return false; @@ -558,14 +558,14 @@ static uint32_t rm_fs_sc(sc_args_t args) { // ---- Spawning new processes & giving them ressources -static uint32_t new_proc_sc(sc_args_t args) { +uint32_t new_proc_sc(sc_args_t args) { process_t *new_proc = new_process(current_process()); if (new_proc == 0) return 0; return new_proc->pid; } -static uint32_t bind_fs_sc(sc_args_t args) { +uint32_t bind_fs_sc(sc_args_t args) { bool ok = false; char* old_name = 0; @@ -594,7 +594,7 @@ end_bind_fs: return ok; } -static uint32_t bind_fd_sc(sc_args_t args) { +uint32_t bind_fd_sc(sc_args_t args) { bool ok = false; fs_handle_t *h = 0; @@ -613,7 +613,7 @@ end_bind_fd: return ok; } -static uint32_t proc_exec_sc(sc_args_t args) { +uint32_t proc_exec_sc(sc_args_t args) { bool ok = false; process_t *p = 0; @@ -650,7 +650,7 @@ end_exec: return ok; } -static uint32_t proc_status_sc(sc_args_t args) { +uint32_t proc_status_sc(sc_args_t args) { proc_status_t *st = (proc_status_t*)args.b; probe_for_write(st, sizeof(proc_status_t)); @@ -661,7 +661,7 @@ static uint32_t proc_status_sc(sc_args_t args) { return true; } -static uint32_t proc_kill_sc(sc_args_t args) { +uint32_t proc_kill_sc(sc_args_t args) { proc_status_t *st = (proc_status_t*)args.b; probe_for_write(st, sizeof(proc_status_t)); @@ -674,7 +674,7 @@ static uint32_t proc_kill_sc(sc_args_t args) { return true; } -static uint32_t proc_wait_sc(sc_args_t args) { +uint32_t proc_wait_sc(sc_args_t args) { proc_status_t *st = (proc_status_t*)args.c; probe_for_write(st, sizeof(proc_status_t)); |