aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/core/thread.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-19 22:57:53 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-19 22:57:53 +0100
commit13db03fcc4a476c8881ccafe0852e72410c67b3a (patch)
tree2064def0c74cb78cf2a532766b4e1d28e571ab41 /src/kernel/core/thread.c
parentadc5a421917dd6e23a2fc01dc9fb2a9f881c291d (diff)
downloadkogata-13db03fcc4a476c8881ccafe0852e72410c67b3a.tar.gz
kogata-13db03fcc4a476c8881ccafe0852e72410c67b3a.zip
Add kernel worker threads for handling various tasks (eg. interrupts)
Diffstat (limited to 'src/kernel/core/thread.c')
-rw-r--r--src/kernel/core/thread.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c
index e62b5a8..7f9f25e 100644
--- a/src/kernel/core/thread.c
+++ b/src/kernel/core/thread.c
@@ -6,6 +6,7 @@
#include <frame.h>
#include <paging.h>
+#include <worker.h>
void save_context_and_enter_scheduler(saved_context_t *ctx);
void resume_context(saved_context_t *ctx);
@@ -155,6 +156,7 @@ thread_t *new_thread(entry_t entry, void* data) {
// ========== //
static void irq0_handler(registers_t *regs) {
+ worker_notify_time(1000000 / TASK_SWITCH_FREQUENCY);
if (current_thread != 0) {
save_context_and_enter_scheduler(&current_thread->ctx);
}
@@ -195,6 +197,16 @@ void pause() {
resume_interrupts(st);
}
+void usleep(int usecs) {
+ void sleeper_resume(void* t) {
+ thread_t *thread = (thread_t*)t;
+ resume_thread(thread, true);
+ }
+ if (current_thread == 0) return;
+ bool ok = worker_push_in(usecs, sleeper_resume, current_thread);
+ if (ok) pause();
+}
+
void exit() {
current_thread->state = T_STATE_FINISHED;
// TODO : add job for deleting the thread, or whatever
@@ -202,16 +214,21 @@ void exit() {
ASSERT(false);
}
-void resume_thread(thread_t *thread, bool run_at_once) {
+bool resume_thread(thread_t *thread, bool run_at_once) {
+ bool ret = false;
+
bool st = disable_interrupts();
if (thread->state == T_STATE_PAUSED) {
+ ret = true;
thread->state = T_STATE_RUNNING;
enqueue_thread(thread, false);
}
if (run_at_once) yield();
resume_interrupts(st);
+
+ return ret;
}
/* vim: set ts=4 sw=4 tw=0 noet :*/