aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-11 16:50:13 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-11 16:50:13 +0100
commit64b9108a58d3483e9b63511c4cf74b12dceeb0f6 (patch)
tree7a3352828a318bcf0126f50ac3d31c8b16540703 /src/kernel
parent9b9ef5a2c0ec8e66c7da24c4229d89a90a10e914 (diff)
downloadkogata-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.c2
-rw-r--r--src/kernel/core/kmalloc.c6
-rw-r--r--src/kernel/core/paging.c8
-rw-r--r--src/kernel/core/thread.c68
-rw-r--r--src/kernel/include/thread.h4
-rw-r--r--src/kernel/user/syscall.c80
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));