summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/Makefile2
-rw-r--r--src/kernel/task/sched.c24
-rw-r--r--src/kernel/task/sched.h9
-rw-r--r--src/kernel/task/task.c30
-rw-r--r--src/kernel/task/task.h2
5 files changed, 46 insertions, 21 deletions
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index eb69cfc..e807fc0 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -1,7 +1,7 @@
Out = kernel.elf
Obj = core/loader_.o core/kmain.o core/sys.o \
core/monitor.o task/timer.o \
- task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o \
+ task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o task/sched.o \
lib/stdlib.o lib/bitset.o lib/mutex.o \
mem/mem.o mem/paging.o mem/gdt.o mem/heap.o mem/seg.o \
ipc/shm.o ipc/object.o ipc/request.o \
diff --git a/src/kernel/task/sched.c b/src/kernel/task/sched.c
new file mode 100644
index 0000000..d2a4c5b
--- /dev/null
+++ b/src/kernel/task/sched.c
@@ -0,0 +1,24 @@
+#include "sched.h"
+#include <core/sys.h>
+#include <mem/mem.h>
+
+static struct thread *queue = 0, *last = 0;
+
+void sched_enqueue(struct thread *t) {
+ t->queue_next = 0;
+ if (queue == 0) {
+ queue = last = t;
+ } else {
+ last->queue_next = t;
+ last = t;
+ }
+}
+
+struct thread *sched_dequeue() {
+ if (queue == 0) return 0;
+ struct thread *it = queue;
+ ASSERT((it->queue_next == 0 && it == last) || it != last);
+ queue = it->queue_next;
+ if (queue == 0) last = 0;
+ return it;
+}
diff --git a/src/kernel/task/sched.h b/src/kernel/task/sched.h
new file mode 100644
index 0000000..1233a44
--- /dev/null
+++ b/src/kernel/task/sched.h
@@ -0,0 +1,9 @@
+#ifndef DEF_SCHED_H
+#define DEF_SCHED_H
+
+#include "task.h"
+
+void sched_enqueue(struct thread *t);
+struct thread *sched_dequeue();
+
+#endif
diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c
index 68cb249..ccc7cc1 100644
--- a/src/kernel/task/task.c
+++ b/src/kernel/task/task.c
@@ -1,4 +1,5 @@
#include "task.h"
+#include "sched.h"
#include <core/sys.h>
#include <core/monitor.h>
#include <mem/mem.h>
@@ -56,25 +57,9 @@ void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint3
}
}
-/* Looks through the list of threads, finds the next thread to run. */
-static struct thread *thread_next() {
- if (current_thread == 0 || current_thread == idle_thread) current_thread = threads;
- struct thread *ret = current_thread;
- while (1) {
- ret = ret->next;
- if (ret == 0) ret = threads;
- if (ret->state == TS_RUNNING) {
- return ret;
- }
- if (ret == current_thread) {
- return idle_thread;
- }
- }
-}
-
/* Called when a timer IRQ fires. Does a context switch. */
void tasking_switch() {
- if (threads == 0) PANIC("No more threads to run !");
+ if (processes == 0) PANIC("No processes are running !");
asm volatile("cli");
uint32_t esp, ebp, eip;
@@ -91,9 +76,12 @@ void tasking_switch() {
current_thread->esp = esp;
current_thread->ebp = ebp;
current_thread->eip = eip;
+ if (current_thread->state == TS_RUNNING && current_thread != idle_thread) sched_enqueue(current_thread);
}
- current_thread = thread_next();
+ current_thread = sched_dequeue();
+ if (current_thread == 0) current_thread = idle_thread;
+
pagedir_switch(current_thread->process->pagedir);
gdt_setKernelStack(((uint32_t)current_thread->kernelStack_addr) + current_thread->kernelStack_size);
@@ -147,7 +135,10 @@ void thread_goInactive() {
/* Wakes up the given thread. */
void thread_wakeUp(struct thread* t) {
- if (t->state == TS_WAKEWAIT) t->state = TS_RUNNING;
+ if (t->state == TS_WAKEWAIT) {
+ t->state = TS_RUNNING;
+ sched_enqueue(t);
+ }
}
/* Returns the privilege level of the current process. */
@@ -278,6 +269,7 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void *
t->eip = (uint32_t)thread_run;
t->state = TS_RUNNING;
+ sched_enqueue(t);
if (threads == 0) {
threads = t;
diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h
index 3b7d9af..a664258 100644
--- a/src/kernel/task/task.h
+++ b/src/kernel/task/task.h
@@ -45,7 +45,7 @@ struct thread {
uint32_t kernelStack_size;
struct segment_map *userStack_seg;
- struct thread *next; //Forms a linked list
+ struct thread *next, *queue_next; //queue_next is used in sched.c
};
extern struct thread *current_thread;