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 void rpc1(msg) /* preprocess RPC request */
28 pix = msg->control.receiver.pix;
30 if (p->mark != msg->control.receiver.mark)
31 senderr(RTEREFTN, &msg->control.sender);
32 msg1 = (message *) ballocate(sizeof(message));
33 if (msg1 == NULL) errsignal(RTEMEMOV);
34 moveblock((char *) msg, (char *) msg1, (word) sizeof(message));
35 prot = msg->control.par;
36 if (isenabled(pix, prot))
38 p->msgqueue = minsert(p->msgqueue, msg1);
39 if (p->status == ACCEPTING) activate(pix);
41 else p->rpcwait = minsert(p->rpcwait, msg1);
47 if (rpcready(thispix)) rpc3();
51 void rpc3() /* Actual remote procedure call */
56 msg = mfront(thisp->msgqueue); /* remove first RPC message (enabled) */
59 stderr, "rpc(thisp=%d) from: node=%d, pix=%d, mark=%d\n",
61 msg->control.sender.node,
62 msg->control.sender.pix,
63 msg->control.sender.mark
66 thisp->msgqueue = qremove(thisp->msgqueue);
67 pushmask(thispix); /* disable all procedures */
68 prot = msg->control.par;
70 slopen(prot, &thisp->procref, &ah, &am); /* open procedure object */
74 mess2obj( thisp, &(msg->control.sender), &v );
75 storevirt( v, am+M[ am ]+RPCDL ); /* set up remote DL */
78 moveparams(thispix, am, msg, PARIN, SAVEPAR);
80 go(ah, am); /* transfer control to procedure */
87 void rpcend(msg) /* After return from RPC */
93 pix = msg->control.receiver.pix;
95 fprintf(stderr,"activate after rpc(thisp=%d)\n",pix);fflush(stderr);
98 am = p->M[ temporary ]; /* template physical address */
99 moveparams(pix, am, msg, PAROUT, SAVEPAR);
100 activate(pix); /* resume process waiting for RPC */
104 static void bitaccess(pix, prot, bytenr, bitmask)
111 bitnr = prot-prototype[ process[ pix ].prot ]->maskbase;
113 *bitmask = (char)(unsigned char)( 1 << (bitnr % 8) );
117 void enable(pix, prot) /* Enable remote procedure */
124 m = top(process[ pix ].rpcmask);
125 bitaccess(pix, prot, &bytenr, &bitmask);
126 m[ bytenr ] |= bitmask;
130 void disable(pix, prot) /* Disable remote procedure */
137 m = top(process[ pix ].rpcmask);
138 bitaccess(pix, prot, &bytenr, &bitmask);
139 m[ bytenr ] &= ~ bitmask;
143 static bool isenabled(pix, prot) /* Check if RPC allowed */
150 m = top(process[ pix ].rpcmask);
151 bitaccess(pix, prot, &bytenr, &bitmask);
152 return( m[ bytenr ] & bitmask );
156 void pushmask(pix) /* Push empty RPC mask onto stack */
162 size = prototype[ process[ pix ].prot ]->masksize;
163 m = (mask) ballocate(size);
164 if (m == NULL) errsignal(RTEMEMOV);
165 for (i = 0; i < size; i++ ) m[ i ] = '\0'; /* disable all */
166 process[ pix ].rpcmask = push(process[ pix ].rpcmask, m);
170 static void dupmask(pix) /* Duplicate RPC mask from stack top */
176 size = prototype[ process[ pix ].prot ]->masksize;
177 m = (mask) ballocate(size);
178 if (m == NULL) errsignal(RTEMEMOV);
179 moveblock(top(process[ pix ].rpcmask), m, (word) size);
180 process[ pix ].rpcmask = push(process[ pix ].rpcmask, m);
184 void popmask(pix) /* Pop RPC mask from stack (restore) */
189 m = top(process[ pix ].rpcmask);
190 process[ pix ].rpcmask = pop(process[ pix ].rpcmask);
195 void evaluaterpc(pix) /* Check if any waiting RPC is enabled */
201 q = process[ pix ].rpcwait;
207 if (isenabled(pix, msg->control.par))
209 process[ pix ].msgqueue = mpush(process[ pix ].msgqueue, msg);
210 process[ pix ].rpcwait = mdelete(process[ pix ].rpcwait, msg);
214 } while (q != process[ pix ].rpcwait);
219 void rpc_accept(length) /* Accept remote procedure call */
225 for (i = 0; i < length; i++)
226 enable(thispix, virtprot(M[ ic++ ]));
227 evaluaterpc(thispix);
228 if (!rpcready(thispix))
229 passivate(ACCEPTING);
233 static bool rpcready(pix)
241 while (!qempty(p->msgqueue))
243 msg = mfront(p->msgqueue);
244 prot = msg->control.par;
245 if (isenabled(pix, prot)) return(TRUE);
246 p->msgqueue = qremove(p->msgqueue);
247 p->rpcwait = minsert(p->rpcwait, msg);
253 word virtprot(prot) /* Get actual prototype for virtual */
260 prot = absolute(prot);
261 virtnr = prototype[ prot ]->virtnumber;
262 if (virtnr != -1) prot = M[ prototype[ thisp->prot ]->virtlist+virtnr ];
263 if (sign) return(-prot); else return(prot);