summaryrefslogtreecommitdiffstats
path: root/proc/scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'proc/scheduler.c')
-rw-r--r--proc/scheduler.c70
1 files changed, 52 insertions, 18 deletions
diff --git a/proc/scheduler.c b/proc/scheduler.c
index 29f45b5..ba00abc 100644
--- a/proc/scheduler.c
+++ b/proc/scheduler.c
@@ -1,9 +1,11 @@
#include "scheduler.h"
#include "api/error.h"
#include "hal/smp.h"
+#include "lib/printf.h"
#include "sys/objdir.h"
#include "proc/init.h"
#include "proc/process.h"
+#include "proc/ipc.h"
//TODO: Better scheduling algorithm than round robin.
static struct pcb_header *s_running_list;
@@ -18,12 +20,18 @@ s_scheduler_swap_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);
+ jove_obj_t target_pagedir = objdir_peeklocal(target_rootdir, PCB_ROOTDIR_PAGEDIR_I);
+
obj_release(target_rootdir);
processor_setpcb(proc, target_pcb_obj);
_scheduler_switch_pcb_arch(target_pcb);
- scheduler_switch(pcb_getksp_ref(current_pcb), pcb_getksp(target_pcb));
+
+ scheduler_switch(
+ pcb_getksp_ref(current_pcb),
+ pcb_getksp(target_pcb),
+ (void*)obj_getvalue((jove_owned_obj_t*)&target_pagedir));
}
int scheduler_yield(pid_t target_pid)
@@ -59,6 +67,8 @@ s_enqueue_pcb(struct pcb_header *pcb, struct pcb_header *list)
void
scheduler_block_for_mail(struct pcb_header *pcb, uintmax_t timeout, pid_t yield_target)
{
+ ipc_klogf("Blocking PID %i for %i ticks for %i\n",
+ pcb_getpid((pcb_t*)pcb), timeout, yield_target);
pcb->state = PCB_STATE_BLOCKED_MAIL;
s_enqueue_pcb(pcb, s_mail_queue);
@@ -88,24 +98,31 @@ s_schedule_mail_queue(void)
while(pcb) {
struct pcb_header *next_pcb = pcb->sched_next;
- if(pcb->send.obj) {
- struct pcb_header *send_target = (struct pcb_header*)pcb_frompid(pcb->send.pid);
- if(send_target->recv.pid == 0 || send_target->recv.pid == pcb->pid) {
- objdir_swapobj(send_target->recv.obj, pcb->send.obj);
- send_target->recv.pid = pcb->pid;
-
- s_enqueue_pcb(pcb, s_running_list);
- s_running_list = pcb;
- goto loop_end;
- }
+ struct port *pcb_port = pcb_getport((pcb_t*)pcb);
+ if(port_poll_send(pcb_port)) {
+ //Send buffer is full. Try to transfer to target recv buffer.
+ //First check if the target recv buffer has space.
+ struct port *recv_port = port_get_send_target(pcb_port);
+ if(port_poll_recv(recv_port)) continue;
+
+ //Now check if the recv buffer is accepting from this port.
+ struct port *recv_target = port_get_recv_target(recv_port);
+ if(recv_target != 0 && pcb_port != recv_target) continue;
+
+ //This never hits, but if things change in impl we may have to abort here.
+ if(port_recv(recv_port, pcb_port) < 0) continue;
+ s_enqueue_pcb(pcb, s_running_list);
+ s_running_list = pcb;
}
- if(pcb->recv.obj) {
+ if(port_poll_recv(pcb_port)) {
+ //Recv buffer is full, so unblock.
s_enqueue_pcb(pcb, s_running_list);
s_running_list = pcb;
- goto loop_end;
}
if(s_this_tick >= pcb->block_until) {
+ ipc_klogf("Unblocking %i due to timeout\n", pcb_getpid((pcb_t*)pcb));
+
s_enqueue_pcb(pcb, s_running_list);
s_running_list = pcb;
}
@@ -147,10 +164,27 @@ void scheduler_init(jove_owned_obj_t *pcb_obj, void *process_main)
processor_t *proc = processor_current();
processor_setpcb(proc, pcb_obj);
- s_running_list = pcb_header;
+ jove_owned_obj_t syscall_stack = init_pop_alloc();
+ jove_owned_obj_t interrupt_stack = init_pop_alloc();
- __asm__("movq %0, %%rsp; \
- xorq %%rbp, %%rbp; \
- jmp %1"::
- "m"(pcb_header->ksp), "r"(process_main));
+ pcb_set_syscall_stack((pcb_t*)pcb_header, obj_getvalue(&syscall_stack));
+ pcb_set_interrupt_stack((pcb_t*)pcb_header, obj_getvalue(&interrupt_stack));
+
+ kprintf("Syscall stack %p %p\n", *__syscall_stack_mapping, pcb_get_syscall_stack((pcb_t*)pcb_header));
+ kprintf("Interrupt stack %p %p\n", *__interrupt_stack_mapping, pcb_get_interrupt_stack((pcb_t*)pcb_header));
+
+ _scheduler_switch_pcb_arch((pcb_t*)pcb_header);
+
+ jove_owned_obj_t *pagedir_obj = pcb_getpagedir(_rootdir_obj);
+ void *pagedir = (void*)obj_getvalue(pagedir_obj);
+ obj_release(pagedir_obj);
+
+ pcb_map_syscall_stack((pcb_t*)pcb_header);
+ pcb_map_interrupt_stack((pcb_t*)pcb_header);
+
+ s_running_list = pcb_header;
+ __asm__ volatile("\
+ movq %0, %%rsp; \
+ xorq %%rbp, %%rbp; \
+ jmpq %1":: "r"(pcb_header->ksp), "r"(process_main));
}