summaryrefslogtreecommitdiffstats
path: root/proc/process.c
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-10-13 22:31:43 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-10-13 22:31:43 -0400
commit548506392b789f58b1556a6ffca917441e1d89fd (patch)
tree58e4b747446ea64e7951e523353f58510b3a8b2f /proc/process.c
parentc5e3bb7917689bc9ed54fee23a143144fade802d (diff)
downloadjove-kernel-548506392b789f58b1556a6ffca917441e1d89fd.tar.gz
jove-kernel-548506392b789f58b1556a6ffca917441e1d89fd.tar.bz2
jove-kernel-548506392b789f58b1556a6ffca917441e1d89fd.zip
ipc functions. work on process spawning
Diffstat (limited to 'proc/process.c')
-rw-r--r--proc/process.c124
1 files changed, 69 insertions, 55 deletions
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 <string.h>
+#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;