From 548506392b789f58b1556a6ffca917441e1d89fd Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Tue, 13 Oct 2026 22:31:43 -0400 Subject: ipc functions. work on process spawning --- proc/process.c | 124 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 55 deletions(-) (limited to 'proc/process.c') diff --git a/proc/process.c b/proc/process.c index f0b83c6..f659c24 100644 --- a/proc/process.c +++ b/proc/process.c @@ -2,9 +2,10 @@ #include "api/error.h" #include "api/process.h" #include "hal/smp.h" +#include "proc/ipc.h" #include "proc/scheduler.h" #include "sys/objdir.h" -#include +#include "lib/string.h" struct rbtree_node *pcb_tree; pid_t __next_pid = 1; @@ -23,74 +24,81 @@ pcb_new(jove_owned_obj_t *pcb_obj, size_t size, jove_owned_obj_t *rootdir_obj) pcb_header->tree_node.get_key = (void*)pcb_getpid; pcb_tree = rbtree_insert(pcb_tree, &pcb_header->tree_node); + pcb_header->mailbox.owner = pcb_header->pid; + pcb_header->state = PCB_STATE_EMBRYO; - pcb_header->ksp = (void*)pcb_obj + size - sizeof(uintmax_t); + pcb_header->ksp = (void*)(__syscall_stack + 0x1000 - sizeof(void*)); return _pcb_new_arch((pcb_t*)pcb_header); } int pcb_send(pcb_t *pcb, pid_t target, jove_owned_obj_t *subject, size_t timeout) { - struct pcb_header *pcb_header = (struct pcb_header*)pcb; - struct pcb_header *target_pcb = (struct pcb_header*)rbtree_search(pcb_tree, target); + //Validate that the target PCB has a valid port. + pcb_t *target_pcb = (pcb_t*)rbtree_search(pcb_tree, target); if(target_pcb == 0) { return -EBADPROC; } - if(target_pcb->recv.obj == NULL && - (target_pcb->recv.pid == pcb_getpid(pcb) || target_pcb->recv.pid == 0)) - { - target_pcb->recv.obj = subject; - target_pcb->recv.pid = pcb_getpid(pcb); - return scheduler_yield(target); - } - - if(timeout == 0) { - return -EFULL; - } + struct port *pcb_port = pcb_getport(pcb); + struct port *target_port = pcb_getport(target_pcb); - pcb_header->send.obj = subject; - pcb_header->send.pid = target; - - scheduler_block_for_mail(pcb_header, timeout, target); + //Try to send to either the send buffer or the target recv buffer. + int port_send_result = port_send(pcb_port, target_port, subject); - if(pcb_header->send.obj) return -ETIMEOUT; + if(port_send_result < 0) { + //Port send buffer was full. Wait for it to clear, or timeout. + if(timeout == 0) return -EFULL; + scheduler_block_for_mail((struct pcb_header*)pcb, timeout, target); + if((port_send_result = port_send(pcb_port, target_port, subject)) < 0) { + //If the send buffer is still full, then we timed out. + return -ETIMEOUT; + } + } + if(port_send_result == 1) { + //We sent to the port, but it's stuck in the send buffer. + scheduler_block_for_mail((struct pcb_header*)pcb, timeout, target); + if(port_poll_send(pcb_port)) { + //If the send buffer is still full, then we timed out. + port_take_send(pcb_port, subject); + return -ETIMEOUT; + } + } return 0; } int pcb_recv(pcb_t *pcb, pid_t target, jove_owned_obj_t *dest_obj, size_t timeout) { - struct pcb_header *pcb_header = (struct pcb_header*)pcb; - struct pcb_header *target_pcb = (struct pcb_header*)rbtree_search(pcb_tree, target); - if(target_pcb == 0) { - return -EBADPROC; - } - - if(pcb_header->recv.obj) { - goto recv_success; - return 0; + struct port *target_port = NULL; + if(target == 0) { + //If the target is zero, we're accepting from all send targets. + pcb_t *target_pcb = (pcb_t*)rbtree_search(pcb_tree, target); + if(target_pcb == 0) { + return -EBADPROC; + } + target_port = pcb_getport(target_pcb); } - if(timeout == 0) { - return -EEMPTY; + struct port *pcb_port = pcb_getport(pcb); + + //Block PCB port from recieving from anything other than the target. + port_set_recv_target(pcb_port, target_port); + struct port *recv_from = port_take_recv(pcb_port, dest_obj); + + if(recv_from == 0) { + if(timeout == 0) { + //If non-blocking, leave immediately. + return -EEMPTY; + } + scheduler_block_for_mail((struct pcb_header*)pcb, timeout, target); + recv_from = port_take_recv(pcb_port, dest_obj); + if(recv_from == 0) { + //If blocking, and timeout expired, then we timed out. + return -ETIMEOUT; + } } - - pcb_header->recv.pid = target; - scheduler_block_for_mail(pcb_header, timeout, target); - - if(!pcb_header->recv.obj) { - pcb_header->recv.pid = -1; - return -ETIMEOUT; - } - -recv_success: - objdir_swapobj(pcb_header->recv.obj, dest_obj); - obj_release(pcb_header->recv.obj); - pcb_header->recv.obj = 0; - pcb_header->recv.pid = -1; - - return 0; + return port_get_owner(recv_from); } pcb_t *pcb_frompid(pid_t pid) @@ -104,49 +112,55 @@ process_current(void) return processor_getpcb(((processor_t*)processor_current())); } -pid_t +inline pid_t pcb_getpid(pcb_t *pcb) { return ((struct pcb_header*)pcb)->pid; } -jove_obj_t* +inline jove_obj_t* pcb_getrootdir(pcb_t *pcb) { return ((struct pcb_header*)pcb)->rootdir; } -jove_owned_obj_t* +inline jove_owned_obj_t* pcb_getpagedir(jove_owned_obj_t *rootdir_obj) { return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_PAGEDIR_I); } -jove_owned_obj_t* +inline jove_owned_obj_t* pcb_getself(jove_owned_obj_t *rootdir_obj) { return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_SELF_I); } -enum pcb_state +inline struct port* +pcb_getport(pcb_t *pcb) +{ + return &((struct pcb_header*)pcb)->mailbox; +} + +inline enum pcb_state pcb_getstate(pcb_t *pcb) { return ((struct pcb_header*)pcb)->state; } -intmax_t +inline intmax_t pcb_getstatecode(pcb_t *pcb) { return ((struct pcb_header*)pcb)->state_code; } -void* +inline void* pcb_getksp(pcb_t *pcb) { return ((struct pcb_header*)pcb)->ksp; } -void** +inline void** pcb_getksp_ref(pcb_t *pcb) { return &((struct pcb_header*)pcb)->ksp; -- cgit v1.2.3