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