summaryrefslogtreecommitdiffstats
path: root/proc/scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'proc/scheduler.c')
-rw-r--r--proc/scheduler.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/proc/scheduler.c b/proc/scheduler.c
index 852cfef..875bcc4 100644
--- a/proc/scheduler.c
+++ b/proc/scheduler.c
@@ -1,3 +1,55 @@
#include "scheduler.h"
+#include "api/error.h"
+#include "hal/smp.h"
+#include "sys/objdir.h"
+#include "proc/init.h"
+#include "proc/process.h"
+static struct pcb_header *s_ready_queue;
+static inline int
+s_scheduler_yield_pcb(processor_t *proc, pcb_t *current_pcb, pcb_t *target_pcb)
+{
+ jove_owned_obj_t *target_rootdir = obj_take(pcb_getrootdir(target_pcb));
+ jove_owned_obj_t *target_pcb_obj = pcb_getself(target_rootdir);
+
+ processor_setpcb(proc, target_pcb_obj);
+
+ obj_release(target_rootdir);
+ _scheduler_switch_pcb_arch(target_pcb);
+ scheduler_switch(pcb_getksp_ref(current_pcb), pcb_getksp(target_pcb));
+
+ return 0;
+}
+
+
+int scheduler_yield(pid_t target_pid)
+{
+ processor_t *proc = processor_current();
+ pcb_t *current_pcb = obj_deref(processor_getpcb(proc));
+ pcb_t *target_pcb = (pcb_t*)((struct pcb_header*)current_pcb)->sched_next;
+
+ if(target_pid != 0) {
+ pcb_t *target_pcb = pcb_frompid(target_pid);
+ }
+ if(target_pcb == 0) {
+ return -EBADPROC;
+ }
+
+ return s_scheduler_yield_pcb(proc, current_pcb, target_pcb);
+}
+
+void scheduler_init(jove_owned_obj_t *pcb_obj, void *process_main)
+{
+ struct pcb_header *pcb_header = obj_deref(pcb_obj);
+ pcb_header->state = PCB_STATE_RUNNING;
+ pcb_header->sched_next = pcb_header;
+
+ processor_t *proc = processor_current();
+ processor_setpcb(proc, pcb_obj);
+
+ __asm__("movq %0, %%rsp; \
+ xorq %%rbp, %%rbp; \
+ jmp %1"::
+ "m"(pcb_header->ksp), "r"(process_main));
+}