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;
97 am = p->M[ temporary ]; /* template physical address */
98 moveparams(pix, am, msg, PAROUT, SAVEPAR);
99 activate(pix); /* resume process waiting for RPC */
103 static void bitaccess(pix, prot, bytenr, bitmask)
110 bitnr = prot-prototype[ process[ pix ].prot ]->maskbase;
112 *bitmask = (char)(unsigned char)( 1 << (bitnr % 8) );
116 void enable(pix, prot) /* Enable remote procedure */
123 m = top(process[ pix ].rpcmask);
124 bitaccess(pix, prot, &bytenr, &bitmask);
125 m[ bytenr ] |= bitmask;
129 void disable(pix, prot) /* Disable remote procedure */
136 m = top(process[ pix ].rpcmask);
137 bitaccess(pix, prot, &bytenr, &bitmask);
138 m[ bytenr ] &= ~ bitmask;
142 static bool isenabled(pix, prot) /* Check if RPC allowed */
149 m = top(process[ pix ].rpcmask);
150 bitaccess(pix, prot, &bytenr, &bitmask);
151 return( m[ bytenr ] & bitmask );
155 void pushmask(pix) /* Push empty RPC mask onto stack */
161 size = prototype[ process[ pix ].prot ]->masksize;
162 m = (mask) ballocate(size);
163 if (m == NULL) errsignal(RTEMEMOV);
164 for (i = 0; i < size; i++ ) m[ i ] = '\0'; /* disable all */
165 process[ pix ].rpcmask = push(process[ pix ].rpcmask, m);
169 static void dupmask(pix) /* Duplicate RPC mask from stack top */
175 size = prototype[ process[ pix ].prot ]->masksize;
176 m = (mask) ballocate(size);
177 if (m == NULL) errsignal(RTEMEMOV);
178 moveblock(top(process[ pix ].rpcmask), m, (word) size);
179 process[ pix ].rpcmask = push(process[ pix ].rpcmask, m);
183 void popmask(pix) /* Pop RPC mask from stack (restore) */
188 m = top(process[ pix ].rpcmask);
189 process[ pix ].rpcmask = pop(process[ pix ].rpcmask);
194 void evaluaterpc(pix) /* Check if any waiting RPC is enabled */
200 q = process[ pix ].rpcwait;
206 if (isenabled(pix, msg->control.par))
208 process[ pix ].msgqueue = mpush(process[ pix ].msgqueue, msg);
209 process[ pix ].rpcwait = mdelete(process[ pix ].rpcwait, msg);
213 } while (q != process[ pix ].rpcwait);
218 void rpc_accept(length) /* Accept remote procedure call */
224 for (i = 0; i < length; i++)
225 enable(thispix, virtprot(M[ ic++ ]));
226 evaluaterpc(thispix);
227 if (!rpcready(thispix))
228 passivate(ACCEPTING);
232 static bool rpcready(pix)
240 while (!qempty(p->msgqueue))
242 msg = mfront(p->msgqueue);
243 prot = msg->control.par;
244 if (isenabled(pix, prot)) return(TRUE);
245 p->msgqueue = qremove(p->msgqueue);
246 p->rpcwait = minsert(p->rpcwait, msg);
252 word virtprot(prot) /* Get actual prototype for virtual */
259 prot = absolute(prot);
260 virtnr = prototype[ prot ]->virtnumber;
261 if (virtnr != -1) prot = M[ prototype[ thisp->prot ]->virtlist+virtnr ];
262 if (sign) return(-prot); else return(prot);