12 static bool isenabled(word,word);
13 static bool rpcready(word);
14 static void bitaccess(word, word, int *, char *);
15 static void dupmask(word);
17 static bool isenabled();
18 static bool rpcready();
19 static void bitaccess();
20 static void dupmask();
24 * preprocess RPC request
26 void rpc1(message *msg)
32 pix = msg->control.receiver.pix;
34 if (p->mark != msg->control.receiver.mark)
35 senderr(RTEREFTN, &msg->control.sender);
37 msg1 = (message *) ballocate(sizeof(message));
42 moveblock((char *) msg, (char *) msg1, (word) sizeof(message));
43 prot = msg->control.par;
44 if (isenabled(pix, prot)) {
45 p->msgqueue = minsert(p->msgqueue, msg1);
47 if (p->status == ACCEPTING)
51 p->rpcwait = minsert(p->rpcwait, msg1);
57 if (rpcready(thispix))
62 * Actual remote procedure call
69 /* remove first RPC message (enabled) */
70 msg = mfront(thisp->msgqueue);
73 fprintf(stderr, "rpc(thisp=%d) from: node=%d, pix=%d, mark=%d\n",
75 msg->control.sender.node,
76 msg->control.sender.pix,
77 msg->control.sender.mark
80 thisp->msgqueue = qremove(thisp->msgqueue);
81 /* disable all procedures */
83 prot = msg->control.par;
85 /* open procedure object */
86 slopen(prot, &thisp->procref, &ah, &am);
90 mess2obj(thisp, &(msg->control.sender), &v);
91 /* set up remote DL */
92 storevirt(v, am + M[am] + RPCDL);
95 moveparams(thispix, am, msg, PARIN, SAVEPAR);
97 /* transfer control to procedure */
103 /* After return from RPC */
104 void rpcend(message *msg)
109 pix = msg->control.receiver.pix;
113 /* template physical address */
114 am = p->M[temporary];
115 moveparams(pix, am, msg, PAROUT, SAVEPAR);
116 /* resume process waiting for RPC */
121 static void bitaccess(word pix, word prot, int *bytenr, char *bitmask)
125 bitnr = prot-prototype[process[pix].prot]->maskbase;
127 *bitmask = (char)(unsigned char)(1 << (bitnr % 8));
130 /* Enable remote procedure */
131 void enable(word pix, word prot)
137 m = top(process[pix].rpcmask);
138 bitaccess(pix, prot, &bytenr, &bitmask);
139 m[bytenr] |= bitmask;
143 * Disable remote procedure
145 void disable(word pix, word prot)
151 m = top(process[pix].rpcmask);
152 bitaccess(pix, prot, &bytenr, &bitmask);
153 m[bytenr] &= ~ bitmask;
157 * Check if RPC allowed
159 static bool isenabled(word pix, word prot)
165 m = top(process[pix].rpcmask);
166 bitaccess(pix, prot, &bytenr, &bitmask);
167 return m[bytenr] & bitmask;
171 * Push empty RPC mask onto stack
173 void pushmask(word pix)
178 size = prototype[process[pix].prot]->masksize;
179 m = (mask) ballocate(size);
182 for (i = 0; i < size; i++) {
186 process[pix].rpcmask = push(process[pix].rpcmask, m);
190 * Duplicate RPC mask from stack top
192 static void dupmask(word pix)
197 size = prototype[process[pix].prot]->masksize;
198 m = (mask) ballocate(size);
201 moveblock(top(process[pix].rpcmask), m, (word) size);
202 process[pix].rpcmask = push(process[pix].rpcmask, m);
206 * Pop RPC mask from stack (restore)
208 void popmask(word pix)
212 m = top(process[pix].rpcmask);
213 process[pix].rpcmask = pop(process[pix].rpcmask);
218 * Check if any waiting RPC is enabled
220 void evaluaterpc(word pix)
225 q = process[pix].rpcwait;
229 if (isenabled(pix, msg->control.par)) {
230 process[pix].msgqueue =
231 mpush(process[pix].msgqueue, msg);
232 process[pix].rpcwait =
233 mdelete(process[pix].rpcwait, msg);
237 } while (q != process[pix].rpcwait);
242 * Accept remote procedure call
244 void rpc_accept(word length)
249 for (i = 0; i < length; i++)
250 enable(thispix, virtprot(M[ic++]));
252 evaluaterpc(thispix);
254 if (!rpcready(thispix))
255 passivate(ACCEPTING);
259 static bool rpcready(word pix)
266 while (!qempty(p->msgqueue)) {
267 msg = mfront(p->msgqueue);
268 prot = msg->control.par;
269 if (isenabled(pix, prot))
271 p->msgqueue = qremove(p->msgqueue);
272 p->rpcwait = minsert(p->rpcwait, msg);
278 * Get actual prototype for virtual
280 word virtprot(word prot)
286 prot = absolute(prot);
287 virtnr = prototype[ prot ]->virtnumber;
289 prot = M[prototype[thisp->prot]->virtlist + virtnr];