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();
30 int internal_sock, graph_sock, net_sock, connected = 0;
31 struct sockaddr_un svr;
33 char ProgName[255], mygname[80], gname[80], mykname[80], nname[80], mynname[80];
38 ctx_struct parent_ctx;
40 /* IDs of remote instances */
42 /* Direct connection channels */
46 int fcol, bcol, curx=0, cury=0;
49 /* Macro to decode addressing modes : */
50 #define getargument(a, argnr) \
51 switch (eop->args[ argnr ]) \
53 case GLOBAL : a = M[ ic++ ]; break; \
54 case LOCAL : a = c1+M[ ic++ ]; break; \
55 case TEMPLOCAL : a = c2+M[ ic++ ]; break; \
56 case REMOTE : a = M[ M[ ic+1 ] ]+M[ ic ]; ic+=2; break;\
57 case INDIRECT : a = M[ M[ ic++ ] ]; break;\
58 case IMMEDIATE : a = ic++; break;\
59 case CONSTANT : a = M[ ic++ ]; break;\
60 case DOTACCESS : a = M[ display+M[ ic+1 ] ]+M[ ic ]; ic += 2; break;\
61 case NOARGUMENT : return; \
65 * Load code and prototypes from file
67 static void load(char *_filename)
72 /* should suffice on all systems */
75 strcpy(filename, _filename);
76 /* allocate main memory array */
77 M = mallocate(memorysize + 1);
79 abend("Memory size too large (use /m option)\n");
81 addext(filename, ".ccd");
82 if ((fp = fopen(filename, BINARYREAD)) == NULL) {
83 fprintf(stderr, "Cannot open .ccd file\n");
87 /* read static data and code from .ccd file */
89 left = memorysize + 1;
92 abend("Memory size too small (use /m option)\n");
93 n = min(IOBLOCK / sizeof(word), left);
94 n = fread((char *) &M[ ic ], sizeof(word), (int) n, fp);
98 /* now ic = number of words read */
102 /* Get various addresses passed by GENERATOR */
104 /* primitive type desctriptions */
106 /* global temporary variables */
107 temporary = M[ic - 4];
108 /* string constants */
110 /* last prototype number */
111 lastprot = M[ic - 2];
112 /* first free word in memory */
115 /* Read prototypes from .pcd file */
116 addext(filename, ".pcd");
117 if ((fp = fopen(filename, BINARYREAD)) == NULL) {
118 fprintf(stderr,"Cannot open .pcd file\n");
121 for (n = MAINBLOCK; n <= lastprot; n++) {
122 cp = ballocate(sizeof(protdescr));
124 abend("Memory size too large (use /m option)\n");
125 prototype[n] = (protdescr *) cp;
127 if (fread(cp, sizeof(protdescr), 1, fp) != 1)
128 abend("Cannot read .pcd file\n");
132 /* Open trace file */
134 addext(filename, ".trd");
135 if ((tracefile = fopen(filename, "w")) == NULL)
136 abend("Cannot open .trd file\n");
141 * Establish configuration parameters
143 static void initiate(int argc, char **argv)
153 if ((argc == 4) && (strcmp(argv[3], "r") == 0))
158 for(i = 0; i < 255; i++) {
166 strcpy(filename, argv[2]);
167 strcpy(ProgName, argv[2]);
169 strcpy(mynname, argv[1]);
170 strcat(mynname, ".net");
172 sock = socket(AF_UNIX, SOCK_STREAM, 0);
173 bzero(&svr, sizeof(svr));
174 svr.sun_family = AF_UNIX;
175 strcpy(svr.sun_path, mynname);
176 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
177 bind(sock, (struct sockaddr*)&svr, len);
181 /* socket for graphic requests */
182 strcpy(mygname, argv[1]);
183 strcat(mygname, ".gr");
186 /* socket for KERNEL communication */
187 internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
188 bzero(&svr, sizeof(svr));
189 svr.sun_family = AF_UNIX;
190 strcpy(svr.sun_path, argv[1]);
191 strcpy(mykname, argv[1]);
192 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
193 i = connect(internal_sock, (struct sockaddr*)&svr, len);
196 fcntl(internal_sock,F_SETFL, O_NONBLOCK |
197 fcntl(internal_sock,F_GETFL,0));
201 close(internal_sock);
202 internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
203 fcntl(internal_sock, F_SETFL, O_NONBLOCK |
204 fcntl(internal_sock, F_GETFL, 0));
205 i = connect(internal_sock, (struct sockaddr*)&svr, len);
208 setsockopt(internal_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
211 /* socket for network requests */
215 if (select(sock + 1, &rset, &wset, 0, 0))
216 net_sock = accept(sock, (struct sockaddr*)0, (int *)0);
219 fcntl(net_sock, F_SETFL, O_NONBLOCK |
220 fcntl(net_sock, F_GETFL, 0));
221 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
227 /* load code and prototypes */
228 if (filename != NULL)
238 /* pointer to extended opcode in M */
239 eop = (extopcode *)(M + ic);
240 /* save ic for possible redecoding */
243 opcode = ((int) eop->opcode ) & 0xFF ;
249 /* -------------------------------------------------------------------- */
252 void send_to_graph(G_MESSAGE *msg)
254 write(graph_sock, msg, sizeof(G_MESSAGE));
257 int read_from_graph(G_MESSAGE *msg)
260 struct timeval tout = {0, 0};
264 FD_SET(graph_sock, &rset);
267 if (select(graph_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
268 if (FD_ISSET(graph_sock, &rset))
269 return(read(graph_sock,msg,sizeof(G_MESSAGE)));
274 int read_from_net(MESSAGE *msg)
277 struct timeval tout = {0, 0};
281 FD_SET(net_sock, &rset);
284 if (select(net_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
285 if (FD_ISSET(net_sock, &rset))
286 return(read(net_sock, msg, sizeof(MESSAGE)));
292 /* Get graphic resource number */
297 struct sockaddr_un svr;
302 sock = socket(AF_UNIX, SOCK_STREAM, 0);
303 bzero(&svr, sizeof(svr));
304 svr.sun_family = AF_UNIX;
305 strcpy(svr.sun_path, mygname);
306 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
307 bind(sock, (struct sockaddr*)&svr, len);
311 msg.msg_type = MSG_GRAPH;
312 msg.param.pword[0] = GRAPH_ALLOCATE;
313 strcpy(msg.param.pstr, mygname);
314 write(internal_sock, &msg, sizeof(MESSAGE));
315 bzero(&msg, sizeof(MESSAGE));
319 if (select(sock+1, &rset, &wset, 0, 0))
320 graph_sock = accept(sock, (struct sockaddr*)0, (int*)0);
322 if (graph_sock == -1) {
328 fcntl(graph_sock, F_SETFL, O_NONBLOCK|fcntl(graph_sock, F_GETFL, 0));
329 setsockopt(graph_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
336 void writeln_str(char *s)
339 msg.msg_type = MSG_GRAPH;
340 msg.param.pword[1] = GraphRes;
341 msg.param.pword[2] = GRAPH_WRITE;
342 strcpy(msg.param.pstr, s);
345 strcpy(msg.param.pstr, "\n");
350 void write_str(char *s)
353 msg.msg_type = MSG_GRAPH;
354 msg.param.pword[1] = GraphRes;
355 msg.param.pword[0] = GRAPH_WRITE;
356 strcpy(msg.param.pstr, s);
361 void write_char(char a)
365 msg.msg_type = MSG_GRAPH;
366 msg.param.pword[1] = GraphRes;
367 msg.param.pword[0] = GRAPH_PUTCHAR;
380 msg.msg_type = MSG_GRAPH;
381 msg.param.pword[1] = GraphRes;
382 msg.param.pword[0] = GRAPH_READCHAR;
385 st = read_from_graph(&msg);
387 if ((msg.msg_type == MSG_GRAPH) &&
388 (msg.param.pword[0] == GRAPH_READCHAR_RESPONSE))
390 ch = msg.param.pchar;
405 msg.msg_type = MSG_GRAPH;
406 msg.param.pword[1] = GraphRes;
407 msg.param.pword[0] = GRAPH_READLN;
410 st = read_from_graph(&msg);
412 if ((msg.msg_type == MSG_GRAPH) &&
413 (msg.param.pword[0]== GRAPH_READLN_RESPONSE))
419 void read_str(char *s)
425 msg.msg_type = MSG_GRAPH;
426 msg.param.pword[1] = GraphRes;
427 msg.param.pword[0] = GRAPH_READSTR;
430 st = read_from_graph(&msg);
432 if ((msg.msg_type == MSG_GRAPH) &&
433 (msg.param.pword[0]==GRAPH_READSTR_RESPONSE)) {
434 strcpy(ss,msg.param.pstr);
443 * send message to kernel
445 void send_to_kernel(MESSAGE *msg)
447 write(internal_sock, msg, sizeof(MESSAGE));
450 /* send message to net */
451 /* 2010 returns 1 if ok and 0 if node desn't exists */
452 int send_to_net(MESSAGE *msg)
456 struct sockaddr_in svr;
460 k = msg->int_msg.control.receiver.node;
462 /* 2010 check if node exists */
463 m.msg_type = MSG_NET;
464 m.param.pword[0] = NET_NODE_EXIST;
465 m.param.pword[1] = k;
466 m.param.pword[2] = my_ctx.program_id;
467 write(net_sock, &m, sizeof(MESSAGE));
468 bzero(&m, sizeof(MESSAGE));
469 while((m.msg_type != MSG_NET) && (m.param.pword[0] != NET_NODE_EXIST))
470 read(net_sock, &m, sizeof(MESSAGE));
472 if (m.param.pword[1] != 1)
475 strcpy(addr, m.param.pstr);
477 if (RInstance[k] == -1) {
478 bzero(&m,sizeof(MESSAGE));
479 m.msg_type = MSG_VLP;
480 m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE;
481 m.param.pword[1] = my_ctx.program_id;
482 m.param.pword[2] = k;
484 bzero(&m, sizeof(MESSAGE));
487 read(internal_sock, &m, sizeof(MESSAGE));
488 if ((m.msg_type == MSG_VLP) &&
489 (m.param.pword[0] == VLP_REMOTE_INSTANCE_HERE))
493 /*printf("DEBUG: remote instance made with id: "
494 "%d addr %s port %d\n", m.param.pword[1], addr,
495 htons(m.param.pword[8]));*/
496 RInstance[k] = m.param.pword[1];
497 /* Make direct connection */
498 DirConn[k] = socket(AF_INET, SOCK_STREAM, 0);
499 svr.sin_family = AF_INET;
500 svr.sin_addr.s_addr = inet_addr(addr);
501 svr.sin_port = htons(m.param.pword[8]);
502 len = connect(DirConn[k], (struct sockaddr*)&svr, sizeof(svr));
506 writeln_str("Cannot connect remote instance!");
508 fcntl(DirConn[k], F_SETFL, O_NONBLOCK |
509 fcntl(DirConn[k], F_GETFL, 0));
512 if (RInstance[k] != -1) {
513 write(DirConn[k], &(msg->int_msg), sizeof(message));
518 /* -------------------- Check for message on internal socket -------------*/
528 struct timeval tout = {0, 0};
531 /* ----------- Direct connection messages -----
534 for(i = 0; i < 255; i++)
535 if (DirConn[i]!=-1) {
536 FD_SET(DirConn[i], &DirSet);
537 if (maxDirSet<DirConn[i])
538 maxDirSet=DirConn[i];
541 if (select(maxDirSet + 1, &DirSet, 0, 0, (struct timeval *)&tout) > 0) {
542 for(i = 0; i < 255; i++) {
543 if ((DirConn[i] != -1) &&
544 (FD_ISSET(DirConn[i], &DirSet))) {
545 r = read(DirConn[i], &mx, sizeof(mx));
547 memcpy(globmsgqueue + msgtail,&mx,
549 msgtail = (msgtail + 1) % MAXMSGQUEUE;
555 -----------------------------------------*/
558 FD_SET(net_sock, &rset);
559 FD_SET(internal_sock, &rset);
560 if (net_sock > internal_sock)
565 for(i = 0; i < 255; i++) {
566 if (DirConn[i] != -1) {
567 FD_SET(DirConn[i], &rset);
568 if (max < DirConn[i])
573 if (select(max + 1, &rset, 0, 0, (struct timeval *)&tout) > 0) {
575 for(i = 0; i < 255; i++) {
576 if ((DirConn[i] != -1) && (FD_ISSET(DirConn[i], &rset))) {
578 printf("DEBUG: Interp has message on "
579 "direct connection: type %d par %d\n",
580 mx.control.type,mx.control.par);
582 r = read(DirConn[i], &mx, sizeof(mx));
583 if (r > 0 && r == sizeof(mx)) {
584 memcpy(globmsgqueue + msgtail, &mx,
586 msgtail = (msgtail+1) % MAXMSGQUEUE;
592 if (FD_ISSET(net_sock,&rset)) {
593 r = read(net_sock, &m, sizeof(MESSAGE));
598 switch(m.param.pword[0]) {
601 printf("DEBUG: cint net_sock MSG_NET "
602 "NET_PROPAGATE cmd %d\n",
604 memcpy(globmsgqueue + msgtail,
607 msgtail = (msgtail + 1) %
617 if (FD_ISSET(internal_sock, &rset)) {
618 r = read(internal_sock, &m, sizeof(MESSAGE));
623 switch(m.param.pword[0]) {
624 case INT_CLOSE_INSTANCE:
632 if (m.param.pword[0] == NET_PROPAGATE) {
634 printf("DEBUG: cint internal_sock MSG_NET NET_PROPAGATE cmd %d\n",m.param.pword[6]);*/
635 memcpy(globmsgqueue + msgtail,
638 msgtail = (msgtail+1) %
655 m.msg_type = MSG_INT;
656 m.param.pword[0] = INT_CTX_REQ;
658 while ((m.msg_type != MSG_INT) || (m.param.pword[0] != INT_CTX))
659 read(internal_sock, &m, sizeof(MESSAGE));
661 my_ctx.node = m.param.pword[1];
662 my_ctx.program_id = m.param.pword[2];
664 parent_ctx.node = m.param.pword[3];
665 parent_ctx.program_id = m.param.pword[4];
666 RInstance[parent_ctx.node] = parent_ctx.program_id;
668 parent_ctx.node = my_ctx.node;
669 parent_ctx.program_id = my_ctx.program_id;
671 ournode = my_ctx.node;
672 /* strcpy(nname,m.param.pstr);*/
673 /* net_sock = open(nname,O_WRONLY);*/
674 m1.msg_type = MSG_GRAPH;
675 m1.param.pword[0] = GRAPH_SET_TITLE;
676 m1.param.pword[1] = GraphRes;
677 sprintf(m1.param.pstr, "%s ID: %d", ProgName, my_ctx.program_id);
680 strcat(m1.param.pstr, " REMOTE instance");
689 struct sockaddr_in svr;
691 struct hostent *info;
694 msg.msg_type = MSG_NET;
695 msg.param.pword[0] = NET_PROPAGATE;
696 msg.param.pword[1] = MSG_VLP;
697 msg.param.pword[2] = my_ctx.node;
698 msg.param.pword[4] = parent_ctx.node;
699 msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK;
700 msg.param.pword[7] = my_ctx.program_id;
702 sock = socket(AF_INET, SOCK_STREAM, 0);
703 bzero(&svr, sizeof(svr));
704 svr.sin_family = AF_INET;
705 svr.sin_addr.s_addr = INADDR_ANY;
707 bind(sock, (struct sockaddr*)&svr, sizeof(svr));
710 getsockname(sock,(struct sockaddr*)&svr, &len);
711 msg.param.pword[8] = ntohs(svr.sin_port);
712 gethostname(name, &len);
713 info = (struct hostent*)gethostbyname(name);
714 bcopy((char*)info->h_addr, (char*)&svr.sin_addr, info->h_length);
715 sprintf(msg.param.pstr, "%s", inet_ntoa(svr.sin_addr));
716 send_to_kernel(&msg);
718 bzero(&svr, sizeof(svr));
719 DirConn[parent_ctx.node] = accept(sock, (struct sockaddr*)&svr, &len);
720 fcntl(DirConn[parent_ctx.node], F_SETFL, O_NONBLOCK |
721 fcntl(DirConn[parent_ctx.node], F_GETFL, 0));
724 int main(int argc, char **argv)
726 /* initialize executor */
727 initiate(argc, argv);
728 /* initialize running system */
731 GraphRes = get_graph_res();
739 /* set label for continue long jump */
741 /* repeat until exit() is called */
744 /* reschedule current process */
747 /* fetch instruction */