diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-10-13 22:31:43 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-10-13 22:31:43 -0400 |
| commit | 548506392b789f58b1556a6ffca917441e1d89fd (patch) | |
| tree | 58e4b747446ea64e7951e523353f58510b3a8b2f /proc/scheduler.c | |
| parent | c5e3bb7917689bc9ed54fee23a143144fade802d (diff) | |
| download | jove-kernel-548506392b789f58b1556a6ffca917441e1d89fd.tar.gz jove-kernel-548506392b789f58b1556a6ffca917441e1d89fd.tar.bz2 jove-kernel-548506392b789f58b1556a6ffca917441e1d89fd.zip | |
ipc functions. work on process spawning
Diffstat (limited to 'proc/scheduler.c')
| -rw-r--r-- | proc/scheduler.c | 70 |
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)); } |
