1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include "ipc.h"
#include "api/error.h"
#include "proc/process.h"
#include "sys/objdir.h"
#include "jove.h"
inline pid_t port_get_owner(struct port *port)
{
return port->owner;
}
inline struct port *port_get_send_target(struct port *port)
{
return port->send_target;
}
inline struct port *port_get_recv_target(struct port *port)
{
return port->recv_target;
}
inline void port_set_recv_target(struct port *port, struct port *target)
{
port->recv_target = target;
}
inline bool port_poll_send(struct port *port) { return port_get_send_target(port) != 0; }
inline bool port_poll_recv(struct port *port) { return obj_peektype(port->recv) != JOVE_OBJ_NONE; }
int port_take_send(struct port *port, jove_owned_obj_t *dest_obj)
{
jove_owned_obj_t *send_obj = obj_take(&port->send);
if(!port_get_send_target(port)) {
ipc_klogf("Port %p does not have mail to send\n", port);
obj_release(send_obj);
return -EEMPTY;
}
ipc_klogf("Taking obj from %i into obj %p\n", port->send_target, dest_obj);
objdir_swapobj(send_obj, dest_obj);
port->send_target = 0;
obj_release(send_obj);
return 0;
}
struct port *port_take_recv(struct port *port, jove_owned_obj_t *dest_obj)
{
errno = 0;
jove_owned_obj_t *recv_obj = obj_take(&port->recv);
//Validate that the port has an object in the recv object.
if(obj_gettype(recv_obj) == JOVE_OBJ_NONE) {
ipc_klogf("Port %p does not have mail\n", port);
obj_release(recv_obj);
errno = EEMPTY;
return NULL;
}
ipc_klogf("Taking obj from %i into obj %p\n", port->recv_target, dest_obj);
objdir_swapobj(recv_obj, dest_obj);
struct port *recv_port = port_get_recv_target(port);
port_set_recv_target(port, (void*)-1);
obj_release(recv_obj);
return recv_port;
}
int port_send(struct port *source, struct port *target, jove_owned_obj_t *sent_obj)
{
jove_owned_obj_t *target_recv_obj = obj_take(&target->recv);
//Validate that the target is full or is not accepting from this port.
if((port_get_recv_target(target) != 0 && port_get_recv_target(target) != source)
|| port_poll_recv(target)) {
obj_release(target_recv_obj);
ipc_klogf("Target %p is full. Sending to send buffer. \n", target);
jove_owned_obj_t *source_send_obj = obj_take(&source->send);
//Validate that the send buffer has space.
if(port_get_send_target(source)) {
ipc_klogf("Source %p is full\n", source);
obj_release(source_send_obj);
return -EFULL;
}
objdir_swapobj(source_send_obj, sent_obj);
source->send_target = target;
obj_release(source_send_obj);
return 1;
}
objdir_swapobj(target_recv_obj, sent_obj);
target->recv_target = source;
obj_release(target_recv_obj);
return 0;
}
int port_recv(struct port *source, struct port *target)
{
jove_owned_obj_t *source_send_obj = obj_take(&source->send);
jove_owned_obj_t *target_recv_obj = obj_take(&target->recv);
objdir_swapobj(source_send_obj, target_recv_obj);
target->recv_target = source;
source->send_target = NULL;
obj_release(target_recv_obj);
obj_release(source_send_obj);
return 0;
}
|