9 static bool isenabled(word,word);
10 static bool rpcready(word);
11 static void bitaccess(word, word, int *, char *);
12 static void dupmask(word);
14 static bool isenabled();
15 static bool rpcready();
16 static void bitaccess();
17 static void dupmask();
21 * preprocess RPC request
23 void rpc1(message *msg)
29 pix = msg->control.receiver.pix;
31 if (p->mark != msg->control.receiver.mark)
32 senderr(RTEREFTN, &msg->control.sender);
34 msg1 = (message *) ballocate(sizeof(message));
39 moveblock((char *) msg, (char *) msg1, (word) sizeof(message));
40 prot = msg->control.par;
41 if (isenabled(pix, prot)) {
42 p->msgqueue = minsert(p->msgqueue, msg1);
44 if (p->status == ACCEPTING)
48 p->rpcwait = minsert(p->rpcwait, msg1);
54 if (rpcready(thispix))
59 * Actual remote procedure call
66 /* remove first RPC message (enabled) */
67 msg = mfront(thisp->msgqueue);
70 fprintf(stderr, "rpc(thisp=%d) from: node=%d, pix=%d, mark=%d\n",
72 msg->control.sender.node,
73 msg->control.sender.pix,
74 msg->control.sender.mark
77 thisp->msgqueue = qremove(thisp->msgqueue);
78 /* disable all procedures */
80 prot = msg->control.par;
82 /* open procedure object */
83 slopen(prot, &thisp->procref, &ah, &am);
87 mess2obj(thisp, &(msg->control.sender), &v);
88 /* set up remote DL */
89 storevirt(v, am + M[am] + RPCDL);
92 moveparams(thispix, am, msg, PARIN, SAVEPAR);
94 /* transfer control to procedure */
100 /* After return from RPC */
101 void rpcend(message *msg)
106 pix = msg->control.receiver.pix;
110 /* template physical address */
111 am = p->M[temporary];
112 moveparams(pix, am, msg, PAROUT, SAVEPAR);
113 /* resume process waiting for RPC */
118 static void bitaccess(word pix, word prot, int *bytenr, char *bitmask)
122 bitnr = prot-prototype[process[pix].prot]->maskbase;
124 *bitmask = (char)(unsigned char)(1 << (bitnr % 8));
127 /* Enable remote procedure */
128 void enable(word pix, word prot)
134 m = top(process[pix].rpcmask);
135 bitaccess(pix, prot, &bytenr, &bitmask);
136 m[bytenr] |= bitmask;
140 * Disable remote procedure
142 void disable(word pix, word prot)
148 m = top(process[pix].rpcmask);
149 bitaccess(pix, prot, &bytenr, &bitmask);
150 m[bytenr] &= ~ bitmask;
154 * Check if RPC allowed
156 static bool isenabled(word pix, word prot)
162 m = top(process[pix].rpcmask);
163 bitaccess(pix, prot, &bytenr, &bitmask);
164 return m[bytenr] & bitmask;
168 * Push empty RPC mask onto stack
170 void pushmask(word pix)
175 size = prototype[process[pix].prot]->masksize;
176 m = (mask) ballocate(size);
179 for (i = 0; i < size; i++) {
183 process[pix].rpcmask = push(process[pix].rpcmask, m);
187 * Duplicate RPC mask from stack top
189 static void dupmask(word pix)
194 size = prototype[process[pix].prot]->masksize;
195 m = (mask) ballocate(size);
198 moveblock(top(process[pix].rpcmask), m, (word) size);
199 process[pix].rpcmask = push(process[pix].rpcmask, m);
203 * Pop RPC mask from stack (restore)
205 void popmask(word pix)
209 m = top(process[pix].rpcmask);
210 process[pix].rpcmask = pop(process[pix].rpcmask);
215 * Check if any waiting RPC is enabled
217 void evaluaterpc(word pix)
222 q = process[pix].rpcwait;
226 if (isenabled(pix, msg->control.par)) {
227 process[pix].msgqueue =
228 mpush(process[pix].msgqueue, msg);
229 process[pix].rpcwait =
230 mdelete(process[pix].rpcwait, msg);
234 } while (q != process[pix].rpcwait);
239 * Accept remote procedure call
241 void rpc_accept(word length)
246 for (i = 0; i < length; i++)
247 enable(thispix, virtprot(M[ic++]));
249 evaluaterpc(thispix);
251 if (!rpcready(thispix))
252 passivate(ACCEPTING);
256 static bool rpcready(word pix)
263 while (!qempty(p->msgqueue)) {
264 msg = mfront(p->msgqueue);
265 prot = msg->control.par;
266 if (isenabled(pix, prot))
268 p->msgqueue = qremove(p->msgqueue);
269 p->rpcwait = minsert(p->rpcwait, msg);
275 * Get actual prototype for virtual
277 word virtprot(word prot)
283 prot = absolute(prot);
284 virtnr = prototype[ prot ]->virtnumber;
286 prot = M[prototype[thisp->prot]->virtlist + virtnr];