12 #include <netinet/in.h>
13 #include <arpa/inet.h>
19 static void load(char *);
20 static void initiate(int,char **);
21 int main(int,char **);
24 static void initiate();
29 int internal_sock,graph_sock,net_sock,connected=0;
30 struct sockaddr_un svr;
32 char ProgName[255],mygname[80], gname[80],mykname[80], nname[80], mynname[80];
37 ctx_struct parent_ctx;
39 int RInstance[255]; /* IDs of remote instances */
40 int DirConn[255]; /* Direct connection channels */
43 int fcol, bcol, curx=0, cury=0;
47 /* Macro to decode addressing modes : */
48 #define getargument(a, argnr) \
49 switch (eop->args[ argnr ]) \
51 case GLOBAL : a = M[ ic++ ]; break; \
52 case LOCAL : a = c1+M[ ic++ ]; break; \
53 case TEMPLOCAL : a = c2+M[ ic++ ]; break; \
54 case REMOTE : a = M[ M[ ic+1 ] ]+M[ ic ]; ic+=2; break;\
55 case INDIRECT : a = M[ M[ ic++ ] ]; break;\
56 case IMMEDIATE : a = ic++; break;\
57 case CONSTANT : a = M[ ic++ ]; break;\
58 case DOTACCESS : a = M[ display+M[ ic+1 ] ]+M[ ic ]; ic += 2; break;\
59 case NOARGUMENT : return; \
63 static void load(_filename) /* Load code and prototypes from file */
69 char filename[100]; /* should suffice on all systems */
71 strcpy( filename, _filename );
72 M = mallocate(memorysize+1); /* allocate main memory array */
73 if (M == NULL) abend("Memory size too large (use /m option)\n");
75 addext(filename, ".ccd");
76 if ((fp = fopen(filename, BINARYREAD)) == NULL)
78 fprintf(stderr,"Cannot open .ccd file\n");
82 ic = 0; /* read static data and code */
83 left = memorysize+1; /* from .ccd file */
86 if (left == 0) abend("Memory size too small (use /m option)\n");
87 n = min(IOBLOCK/sizeof(word), left);
88 n = fread((char *) &M[ ic ], sizeof(word), (int) n, fp);
91 } while (n != 0); /* now ic = number of words read */
94 /* Get various addresses passed by GENERATOR */
95 ipradr = M[ ic-5 ]; /* primitive type desctriptions */
96 temporary = M[ ic-4 ]; /* global temporary variables */
97 strings = M[ ic-3 ]; /* string constants */
98 lastprot = M[ ic-2 ]; /* last prototype number */
99 freem = M[ ic-1 ]; /* first free word in memory */
101 /* Read prototypes from .pcd file */
102 addext(filename, ".pcd");
103 if ((fp = fopen(filename, BINARYREAD)) == NULL)
105 fprintf(stderr,"Cannot open .pcd file\n");
108 for (n = MAINBLOCK; n <= lastprot; n++ )
110 cp = ballocate(sizeof(protdescr));
111 if (cp == NULL) abend("Memory size too large (use /m option)\n");
112 prototype[ n ] = (protdescr *) cp;
113 if (fread(cp, sizeof(protdescr), 1, fp) != 1)
114 abend("Cannot read .pcd file\n");
118 /* Open trace file */
121 addext(filename, ".trd");
122 if ((tracefile = fopen(filename, "w")) == NULL)
123 abend("Cannot open .trd file\n");
128 static void initiate(argc, argv) /* Establish configuration parameters */
140 if ( (argc==4) && (strcmp(argv[3],"r") == 0) ) remote = TRUE;else remote=FALSE;
150 strcpy(filename,argv[2]);
151 strcpy(ProgName,argv[2]);
153 strcpy(mynname,argv[1]);
154 strcat(mynname,".net");
156 sock = socket(AF_UNIX,SOCK_STREAM,0);
157 bzero(&svr, sizeof(svr));
158 svr.sun_family = AF_UNIX;
159 strcpy(svr.sun_path,mynname);
160 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
161 bind(sock,(struct sockaddr*)&svr, len);
165 /* socket for graphic requests */
166 strcpy(mygname,argv[1]);
167 strcat(mygname,".gr");
171 /* socket for KERNEL communication */
172 internal_sock = socket(AF_UNIX,SOCK_STREAM,0);
173 bzero(&svr, sizeof(svr));
174 svr.sun_family = AF_UNIX;
175 strcpy(svr.sun_path,argv[1]);
176 strcpy(mykname,argv[1]);
177 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
178 i=connect(internal_sock,(struct sockaddr*)&svr,len);
182 fcntl(internal_sock,F_SETFL, O_NONBLOCK|fcntl(internal_sock,F_GETFL,0));
187 close(internal_sock);
188 internal_sock = socket(AF_UNIX,SOCK_STREAM,0);
189 fcntl(internal_sock,F_SETFL, O_NONBLOCK|fcntl(internal_sock,F_GETFL,0));
190 i=connect(internal_sock,(struct sockaddr*)&svr,len);
193 setsockopt(internal_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
195 /* socket for network requests */
196 FD_ZERO(&rset);FD_ZERO(&wset);
198 if (select(sock+1,&rset,&wset,0,0))
199 net_sock = accept(sock,(struct sockaddr*)0,(int *)0);
202 fcntl(net_sock,F_SETFL,O_NONBLOCK|fcntl(net_sock,F_GETFL,0));
203 setsockopt(net_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
209 load(filename); /* load code and prototypes */
218 eop = (extopcode *)(M+ic); /* pointer to extended opcode in M */
219 lastic = ic; /* save ic for possible redecoding */
221 opcode = ((int) eop->opcode ) & 0xFF ;
227 /* -------------------------------------------------------------------- */
230 void send_to_graph(G_MESSAGE *msg)
232 write(graph_sock,msg,sizeof(G_MESSAGE));
235 int read_from_graph(G_MESSAGE *msg)
238 struct timeval tout={0,0};
240 FD_ZERO(&rset);FD_ZERO(&wset);
241 FD_SET(graph_sock,&rset);
244 if (select(graph_sock+1,&rset,&wset,0,(struct timeval *)&tout)>0)
246 if (FD_ISSET(graph_sock,&rset))
247 return(read(graph_sock,msg,sizeof(G_MESSAGE)));
252 int read_from_net(MESSAGE *msg)
255 struct timeval tout={0,0};
257 FD_ZERO(&rset);FD_ZERO(&wset);
258 FD_SET(net_sock,&rset);
261 if (select(net_sock+1,&rset,&wset,0,(struct timeval *)&tout)>0)
263 if (FD_ISSET(net_sock,&rset))
264 return(read(net_sock,msg,sizeof(MESSAGE)));
270 /* Get graphic resource number */
275 struct sockaddr_un svr;
280 sock = socket(AF_UNIX,SOCK_STREAM,0);
281 bzero(&svr,sizeof(svr));
282 svr.sun_family = AF_UNIX;
283 strcpy(svr.sun_path,mygname);
284 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
285 bind(sock,(struct sockaddr*)&svr, len);
289 msg.msg_type = MSG_GRAPH;
290 msg.param.pword[0] = GRAPH_ALLOCATE;
291 strcpy(msg.param.pstr,mygname);
292 write(internal_sock,&msg,sizeof(MESSAGE));
293 bzero(&msg,sizeof(MESSAGE));
294 FD_ZERO(&rset);FD_ZERO(&wset);
296 if (select(sock+1,&rset,&wset,0,0))
297 graph_sock = accept(sock,(struct sockaddr*)0,(int*)0);
299 if (graph_sock == -1)
301 graphics=FALSE;return(0);
305 fcntl(graph_sock,F_SETFL, O_NONBLOCK|fcntl(graph_sock,F_GETFL,0));
306 setsockopt(graph_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
310 } /* get_graph_res */
314 void writeln_str(char *s)
317 msg.msg_type = MSG_GRAPH;
318 msg.param.pword[1] = GraphRes;
319 msg.param.pword[2] = GRAPH_WRITE;
320 strcpy(msg.param.pstr,s);
323 strcpy(msg.param.pstr,"\n");
328 void write_str(char *s)
331 msg.msg_type = MSG_GRAPH;
332 msg.param.pword[1] = GraphRes;
333 msg.param.pword[0] = GRAPH_WRITE;
334 strcpy(msg.param.pstr,s);
339 void write_char(char a)
343 msg.msg_type = MSG_GRAPH;
344 msg.param.pword[1] = GraphRes;
345 msg.param.pword[0] = GRAPH_PUTCHAR;
359 msg.msg_type = MSG_GRAPH;
360 msg.param.pword[1] = GraphRes;
361 msg.param.pword[0] = GRAPH_READCHAR;
365 st = read_from_graph(&msg);
368 if ((msg.msg_type == MSG_GRAPH) &&
369 (msg.param.pword[0]==GRAPH_READCHAR_RESPONSE))
370 {ch = msg.param.pchar;break;}
384 msg.msg_type = MSG_GRAPH;
385 msg.param.pword[1] = GraphRes;
386 msg.param.pword[0] = GRAPH_READLN;
390 st = read_from_graph(&msg);
392 if ((msg.msg_type == MSG_GRAPH) && (msg.param.pword[0]== GRAPH_READLN_RESPONSE))
398 void read_str(char *s)
404 msg.msg_type = MSG_GRAPH;
405 msg.param.pword[1] = GraphRes;
406 msg.param.pword[0] = GRAPH_READSTR;
410 st = read_from_graph(&msg);
413 if ((msg.msg_type == MSG_GRAPH) &&
414 (msg.param.pword[0]==GRAPH_READSTR_RESPONSE))
415 { strcpy(ss,msg.param.pstr);break;}
423 /* send message to kernel */
424 void send_to_kernel(MESSAGE *msg)
426 write(internal_sock,msg,sizeof(MESSAGE));
429 /* send message to net */
430 void send_to_net(MESSAGE *msg)
434 struct sockaddr_in svr;
437 k = msg->int_msg.control.receiver.node;
438 if (RInstance[k]==-1)
440 bzero(&m,sizeof(MESSAGE));
441 m.msg_type = MSG_VLP;
442 m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE;
443 m.param.pword[1] = my_ctx.program_id;
444 m.param.pword[2] = k;
446 bzero(&m,sizeof(MESSAGE));
449 read(internal_sock,&m,sizeof(MESSAGE));
450 if ( (m.msg_type == MSG_VLP) && (m.param.pword[0]==VLP_REMOTE_INSTANCE_HERE)) break;
453 RInstance[k] = m.param.pword[1];
454 /* Make direct connection */
455 DirConn[k] = socket(AF_INET,SOCK_STREAM,0);
456 svr.sin_family = AF_INET;
457 svr.sin_addr.s_addr = inet_addr(m.param.pstr);
458 svr.sin_port = htons(m.param.pword[8]);
459 len = connect(DirConn[k],(struct sockaddr*)&svr,sizeof(svr));
463 writeln_str("Cannot connect remote instance!");
467 fcntl(DirConn[k], F_SETFL,O_NONBLOCK | fcntl(DirConn[k], F_GETFL,0));
471 if (RInstance[k]!=-1)
473 write(DirConn[k],&(msg->int_msg),sizeof(message));
479 /* -------------------- Check for message on internal socket -------------*/
490 struct timeval tout={0,0};
494 /* ----------- Direct connection messages -----*/
500 FD_SET(DirConn[i],&DirSet);
501 if (maxDirSet<DirConn[i]) maxDirSet=DirConn[i];
504 if (select(maxDirSet+1,&DirSet,0,0,(struct timeval *)&tout)>0)
508 if ( (DirConn[i]!=-1) && (FD_ISSET(DirConn[i],&DirSet)) )
510 r=read(DirConn[i],&mx,sizeof(mx));
513 memcpy(globmsgqueue+msgtail,&mx,sizeof(message));
514 msgtail = (msgtail+1) % MAXMSGQUEUE;
520 /*-----------------------------------------*/
523 FD_ZERO(&rset);FD_ZERO(&wset);
524 FD_SET(net_sock,&rset);
525 FD_SET(internal_sock,&rset);
527 if (net_sock>internal_sock) max = net_sock; else max = internal_sock;
529 if (select(max+1,&rset,&wset,0,(struct timeval *)&tout)>0)
532 if (FD_ISSET(net_sock,&rset))
534 r = read(net_sock, &m, sizeof(MESSAGE));
540 switch(m.param.pword[0])
543 memcpy(globmsgqueue+msgtail,&m.int_msg,sizeof(message));
544 msgtail = (msgtail+1) % MAXMSGQUEUE;
552 if (FD_ISSET(internal_sock,&rset))
554 r = read(internal_sock,&m,sizeof(MESSAGE));
561 switch(m.param.pword[0])
563 case INT_CLOSE_INSTANCE: endrun(0);
564 case INT_KILL: endrun(1);
568 if (m.param.pword[0] == NET_PROPAGATE)
570 memcpy(globmsgqueue+msgtail,&m.int_msg,sizeof(message));
571 msgtail = (msgtail+1) % MAXMSGQUEUE;
589 m.msg_type = MSG_INT;
590 m.param.pword[0] = INT_CTX_REQ;
592 while ( (m.msg_type != MSG_INT) || (m.param.pword[0] != INT_CTX) )
593 read(internal_sock,&m,sizeof(MESSAGE));
595 my_ctx.node = m.param.pword[1];
596 my_ctx.program_id = m.param.pword[2];
599 parent_ctx.node = m.param.pword[3];
600 parent_ctx.program_id = m.param.pword[4];
601 RInstance[parent_ctx.node] = parent_ctx.program_id;
605 parent_ctx.node = my_ctx.node;
606 parent_ctx.program_id = my_ctx.program_id;
608 ournode = my_ctx.node;
609 // strcpy(nname,m.param.pstr);
610 // net_sock = open(nname,O_WRONLY);
611 m1.msg_type = MSG_GRAPH;
612 m1.param.pword[0] = GRAPH_SET_TITLE;
613 m1.param.pword[1] = GraphRes;
614 sprintf(m1.param.pstr,
615 "%s ID: %d",ProgName,my_ctx.program_id);
616 if (remote) strcat(m1.param.pstr," REMOTE instance");
625 struct sockaddr_in svr;
627 struct hostent *info;
631 msg.msg_type = MSG_NET;
632 msg.param.pword[0] = NET_PROPAGATE;
633 msg.param.pword[1] = MSG_VLP;
634 msg.param.pword[2] = my_ctx.node;
635 msg.param.pword[4] = parent_ctx.node;
636 msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK;
637 msg.param.pword[7] = my_ctx.program_id;
639 sock = socket(AF_INET,SOCK_STREAM,0);
640 bzero(&svr,sizeof(svr));
641 svr.sin_family = AF_INET;
642 svr.sin_addr.s_addr = INADDR_ANY;
644 bind(sock, (struct sockaddr*)&svr, sizeof(svr));
647 getsockname(sock,(struct sockaddr*)&svr,&len);
648 msg.param.pword[8] = ntohs(svr.sin_port);
649 gethostname(name,&len);
650 info = (struct hostent*)gethostbyname(name);
651 bcopy((char*)info->h_addr,(char*)&svr.sin_addr,info->h_length);
652 sprintf(msg.param.pstr,"%s",inet_ntoa(svr.sin_addr));
653 send_to_kernel(&msg);
655 bzero(&svr,sizeof(svr));
656 DirConn[parent_ctx.node] = accept(sock,(struct sockaddr*)&svr,&len);
657 fcntl(DirConn[parent_ctx.node], F_SETFL,O_NONBLOCK |
658 fcntl(DirConn[parent_ctx.node], F_GETFL,0));
665 initiate(argc, argv); /* initialize executor */
666 runsys(); /* initialize running system */
668 GraphRes = get_graph_res();
669 if ( GraphRes < 0 ) exit(12);
672 if (remote) send_ready();
675 setjmp(contenv); /* set label for continue long jump */
676 while (TRUE) /* repeat until exit() is called */
679 schedule(); /* reschedule current process */
682 decode(); /* fetch instruction */
683 execute(); /* and execute it */