diff options
Diffstat (limited to 'proc/process.c')
| -rw-r--r-- | proc/process.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/proc/process.c b/proc/process.c index 137e35c..62c0269 100644 --- a/proc/process.c +++ b/proc/process.c @@ -1,6 +1,8 @@ #include "process.h" +#include "api/error.h" #include "api/process.h" #include "hal/smp.h" +#include "proc/scheduler.h" #include "sys/objdir.h" #include <string.h> @@ -26,6 +28,71 @@ pcb_new(jove_owned_obj_t *pcb_obj, size_t size, jove_owned_obj_t *rootdir_obj) 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); |
