summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2012-05-19 17:01:56 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2012-05-19 17:01:56 +0200
commitc57a919d019606c7d83fea574159f542e431c199 (patch)
tree3363026b9a30cc3dc1d4dfc57f45b69bb3a986c4
parentd502fce7d4db492690e39c72fc029aa05a65057d (diff)
downloadTCE-c57a919d019606c7d83fea574159f542e431c199.tar.gz
TCE-c57a919d019606c7d83fea574159f542e431c199.zip
Not a bugfix. The multitasking system must be redone.
-rw-r--r--src/kernel/task/sched.cpp18
-rw-r--r--src/kernel/task/sched.h1
-rw-r--r--src/kernel/task/task.cpp12
3 files changed, 24 insertions, 7 deletions
diff --git a/src/kernel/task/sched.cpp b/src/kernel/task/sched.cpp
index d7e16d2..36f6783 100644
--- a/src/kernel/task/sched.cpp
+++ b/src/kernel/task/sched.cpp
@@ -49,3 +49,21 @@ thread *sched_dequeue() {
if (it == 0) return idle_thread;
return it;
}
+
+/* Used by task.c. Removes specified thread from any queue it is in. */
+void sched_remove(thread *t) {
+ for (int i = 0; i < PRIORITIES; i++) {
+ if (queue[i] == t) {
+ queue[i] = t->queue_next;
+ } else if (queue[i] != 0) {
+ thread *it = queue[i];
+ while (it->queue_next != 0) {
+ if (it->queue_next == t) {
+ it->queue_next = t->queue_next;
+ break;
+ }
+ it = it->queue_next;
+ }
+ }
+ }
+}
diff --git a/src/kernel/task/sched.h b/src/kernel/task/sched.h
index 7d0dcd3..1432b02 100644
--- a/src/kernel/task/sched.h
+++ b/src/kernel/task/sched.h
@@ -4,6 +4,7 @@
#include "task.h"
void sched_enqueue(thread *t);
+void sched_remove(thread *t);
thread *sched_dequeue();
#endif
diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp
index 5dea33b..3863850 100644
--- a/src/kernel/task/task.cpp
+++ b/src/kernel/task/task.cpp
@@ -204,7 +204,6 @@ void process_exit(size_t retval) {
(its address is the value given for EIP).
It switches to user mode if necessary and calls the entry point. */
static void thread_run(void* u_esp, thread *thread, thread_entry entry_point, void *data) {
- asm volatile("cli");
pagedir_switch(thread->process->pagedir);
if (thread->process->privilege >= PL_USER) { //User mode !
uint32_t *stack = (uint32_t*)u_esp;
@@ -237,7 +236,6 @@ static void thread_run(void* u_esp, thread *thread, thread_entry entry_point, vo
push %%eax; \
pushl $0x1B; \
push %%ecx; \
- sti; \
iret; \
" : : "b"(esp), "c"(eip));
} else {
@@ -269,12 +267,9 @@ thread::thread(class process *proc, thread_entry entry_point, void *data, void *
stack--; *stack = (uint32_t)u_esp;
stack--; *stack = 0;
esp = (uint32_t)stack;
- ebp = esp + 8;
+ ebp = esp + 16;
eip = (uint32_t)thread_run;
- state = TS_RUNNING;
- sched_enqueue(this);
-
if (proc->threads == 0) {
proc->threads = this;
} else {
@@ -282,6 +277,9 @@ thread::thread(class process *proc, thread_entry entry_point, void *data, void *
while (i->next != 0) i = i->next;
i->next = this;
}
+
+ state = TS_RUNNING;
+ sched_enqueue(this);
}
/* Creates a new process. Creates a struct process and fills it up. */
@@ -310,6 +308,7 @@ process::process(process* _parent, uint32_t _uid, uint32_t _privilege) : fd(12,
/* Deletes given thread, freeing the stack(s). */
static void thread_delete(thread *th) {
+ sched_remove(th);
if (th->process->threads == th) {
th->process->threads = th->next;
} else {
@@ -332,7 +331,6 @@ static void thread_delete(thread *th) {
static void process_finish(process *pr, int retval) {
proc_retval->set(pr->pid, (void*)retval);
-
thread *it = pr->threads;
while (it != 0) {
thread_delete(it);