#include "process.h" #include "api/error.h" #include "api/process.h" #include "hal/smp.h" #include "proc/scheduler.h" #include "sys/objdir.h" #include struct rbtree_node *pcb_tree; pid_t __next_pid = 1; int pcb_new(jove_owned_obj_t *pcb_obj, size_t size, jove_owned_obj_t *rootdir_obj) { struct pcb_header *pcb_header = obj_deref(pcb_obj); memset(pcb_header, 0, size); pcb_header->size = size; pcb_header->pid = __next_pid++; pcb_header->rootdir = obj_release(rootdir_obj); pcb_header->tree_node.get_key = (void*)pcb_getpid; pcb_tree = rbtree_insert(pcb_tree, &pcb_header->tree_node); pcb_header->state = PCB_STATE_EMBRYO; pcb_header->ksp = (void*)pcb_obj + size - sizeof(uintmax_t); 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); 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; } pcb_header->send.obj = subject; pcb_header->send.pid = target; scheduler_block_for_mail(pcb_header, timeout, target); if(pcb_header->send.obj) 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; } if(timeout == 0) { return -EEMPTY; } 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; } pcb_t *pcb_frompid(pid_t pid) { return (pcb_t*)rbtree_search((struct rbtree_node*)pcb_tree, pid); } jove_owned_obj_t* process_current(void) { return processor_getpcb(((processor_t*)processor_current())); } pid_t pcb_getpid(pcb_t *pcb) { return ((struct pcb_header*)pcb)->pid; } jove_obj_t* pcb_getrootdir(pcb_t *pcb) { return ((struct pcb_header*)pcb)->rootdir; } 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* pcb_getself(jove_owned_obj_t *rootdir_obj) { return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_SELF_I); } enum pcb_state pcb_getstate(pcb_t *pcb) { return ((struct pcb_header*)pcb)->state; } intmax_t pcb_getstatecode(pcb_t *pcb) { return ((struct pcb_header*)pcb)->state_code; } void* pcb_getksp(pcb_t *pcb) { return ((struct pcb_header*)pcb)->ksp; } void** pcb_getksp_ref(pcb_t *pcb) { return &((struct pcb_header*)pcb)->ksp; }