/* DFTEST -- test "dfl," a dataflow interpreter (c) 1996, Howard E. Motteler, NAME: dftest USAGE: dftest [-s n] [-r n] [-o output sequence] DESCRIPTION: The dftest program is used to test a "dfl" (dataflow interpreter) project. Dftest reads an output sequence, either from stdin or as a command line argument if the "-o" flag is given. The output sequence is specified as a list of = pairs, e.g., c1=2 c2=4 c3=99 c1=0 c1=2, etc. The can be either an integer or the special symbol "end". After reading an output sequence, dftest forks to become two processes: a sender that writes the specified values to the specified buffers (or channels) and a receiver that reads from buffer (or channel) zero. The sender prints values just before they are sent, and the receiver prints values as soon as they are received. When dftest's receiving process receives an END, or if the number of values received exceeds a fixed limit, it terminates. OPTIONS: -o use instead of stdin as output sequence -s sleep seconds between sends; default is 1 -r receive at most values; default is number sent BUGS: 1. dftest only knows about channels c0-c9 2. dftest currently only receives on channel 0 */ #include #include #include #include "dftest.h" /* parameters and limits */ #define MAXLEN 100 /* longest allowable output sequence */ #define BUFLEN 20 /* temporary char buffer size */ #define INPCHAN 0 #define DEBUG 0 /* initial debug value */ int outval[MAXLEN]; /* array of values to be sent */ int outbuf[MAXLEN]; /* corresponding channels for values */ char buf[BUFLEN]; /* temporary char buffer */ /* main program */ main (argc, argv) int argc; char *argv[]; { int i, j, k, c; int oflag=0, nout=0, debug=DEBUG; int recvlim=0, sendwait=1; char *p; int pid; extern int getopt(); extern char *optarg; extern int optind; extern char *sbase(); /* parse command line input */ while ((c=getopt(argc, argv, "ds:r:o:")) != EOF) switch (c) { case 'd': /* set debug flag */ debug = 1; break; case 's': /* set wait between sends */ sendwait = atoi(optarg); break; case 'r': /* max number of values to receive on channel 0 */ recvlim = atoi(optarg); break; case 'o': /* read output commands from the remaining command line */ oflag = 1; for (i=optind-1,nout=0; i= cmd: %s\n", argv[0], argv[i]); exit(2); } else { outbuf[nout] = argv[i][1]-'0'; if (strncmp("end", argv[i]+3, 3) == 0) outval[nout] = END ; else outval[nout] = atoi(argv[i]+3) ; } break; case '?': /* command line error */ printf("Usage: %s [-d] [-o output sequence]\n", argv[0]); exit(2); break; } if (!oflag) { /* read output commands from stdin */ for (nout = 0, c = getchar(); c != EOF; ) { i = 0; p = buf; while (c != EOF && isspace(c)) c=getchar(); while (c != EOF && !isspace(c) && i 3 && buf[0] == 'c' && buf[2] == '=') { outbuf[nout] = buf[1] - '0'; if (strncmp("end", buf+3, 3) == 0) outval[nout] = END ; else outval[nout] = atoi(buf+3) ; nout++; } else if (i != 0) { printf("%s: bad = cmd: %s\n", argv[0], buf); exit(2); } } } /* semaphore and shared memory initialization */ sinit(); /* initialize or attach to semaphore block */ p = sbase(); for (i=0; i < NBUFS*sizeof(bufrec); i++) *p++ = 0; for (i=0; i < NSEMS; i++) ssig(i); for (i=0; i < NBUFS-3; i++) ssig(READY); /* become two processes: a sender and a receiver */ if ((pid=fork()) != 0) { /* we are the receiving process * * This process (the parent) receives vaues from the INPCHAN * buffer until either END or recvlim values have been received. * Then sclear() is called to deallocate semaphores and free the * shared memory. */ if (recvlim == 0) recvlim = nout; for (i=0, j=0, k=0; k != END && i < recvlim; i++) if ((k=readbuf(INPCHAN)) == END) printf("%s: received end\n", argv[0]); else { printf("%s: received %d\n", argv[0], k); j++; } /* exit after clearing semaphores and shared memory */ printf("%s: received %d values\n", argv[0], j); printf("%s: clearing semaphores\n", argv[0]); sclear(); } else { /* we are the sending process * * This process (the child) process sends the test * data, and terminates quietly when everything has * been sent. */ for (i=0; i 0) sleep(sendwait); } /* Detach from shared memory, but don't delete shared * memory or sem's (other processes may still be using * then) and then exit quietly. */ shmdetatch(); } }