-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathipc.c
More file actions
117 lines (106 loc) · 3.31 KB
/
ipc.c
File metadata and controls
117 lines (106 loc) · 3.31 KB
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
117
// User-level IPC library routines
#include <inc/lib.h>
// Receive a value via IPC and return it.
// If 'pg' is nonnull, then any page sent by the sender will be mapped at
// that address.
// If 'from_env_store' is nonnull, then store the IPC sender's envid in
// *from_env_store.
// If 'perm_store' is nonnull, then store the IPC sender's page permission
// in *perm_store (this is nonzero iff a page was successfully
// transferred to 'pg').
// If the system call fails, then store 0 in *fromenv and *perm (if
// they're nonnull) and return the error.
// Otherwise, return the value sent by the sender
//
// Hint:
// Use 'env' to discover the value and who sent it.
// If 'pg' is null, pass sys_ipc_recv a value that it will understand
// as meaning "no page". (Zero is not the right value, since that's
// a perfectly valid place to map a page.) SUNUS : THAT VALUE IS UTOP!
int32_t
ipc_recv(envid_t *from_env_store, void *pg, int *perm_store)
{
// LAB 4: Your code here.
// Fab 9,2011 SUNUS
int r;
if(!pg)
pg = (void *)UTOP;
if((r = sys_ipc_recv(pg)) < 0)
{
sunus_dbg(1 ,1, ipc_recv,"r = %e\n",r);
return r;
}
if(from_env_store)
*from_env_store = env->env_ipc_from;
if(perm_store)
*perm_store = env->env_ipc_perm;
return env->env_ipc_value;
}
/*
int32_t
ipc_recv(envid_t *from_env_store, void *pg, int *perm_store)
{
// LAB 4: Your code here.
int r;
if (pg == NULL)
pg = (void *) UTOP;
r = sys_ipc_recv(pg);
if (r < 0) {
if (from_env_store)
*from_env_store = 0;
if (perm_store)
*perm_store = 0;
return r;
}
if (from_env_store)
*from_env_store = env->env_ipc_from;
if (perm_store)
*perm_store = env->env_ipc_perm;
return env->env_ipc_value;
}
*/
// Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'.
// This function keeps trying until it succeeds.
// It should panic() on any error other than -E_IPC_NOT_RECV.
//
// Hint:
// Use sys_yield() to be CPU-friendly.
// If 'pg' is null, pass sys_ipc_recv a value that it will understand
// as meaning "no page". (Zero is not the right value.)
void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
// LAB 4: Your code here.
// Fab 9,2011 SUNUS
int r;
int newperm = perm;
if(!pg)
{
pg = (void *)UTOP;
newperm = 0;
}
while((r = sys_ipc_try_send(to_env, val, pg, newperm)) < 0)
{
if(r != -E_IPC_NOT_RECV)
{
sunus_dbg(1,1,ipc_send,"r = %e(%d)\n",r,r);
panic("%e\n",r);
}
sys_yield();
}
sys_yield();
}
/*
void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
// LAB 4: Your code here.
int r;
if (pg == NULL)
pg = (void *) UTOP;
while ((r = sys_ipc_try_send(to_env, val, pg, perm))) {
if (r != -E_IPC_NOT_RECV)
panic("sys_ipc_try_send: %e", r);
}
}
*/