#include "./stdinc.h" // Name: npipe.c // Purpose: Make a pipeline with N identical processes; i.e., it // is equivalent to: // npipe < TestInput | npipe | ... | npipe // where there are N processes. // Usage: npipe [-d] [-n N] // -a Run alternate plumbing algorithm // -d Turn debugging messages on // -n N # processes in pipe // Method: // Consider the case of N=4, a 4-stage pipeline. To minimize code, // want to exploit some regularity in viewing the computation. If // we group the pipeline in the following manner, we see that all // stages except the last are structurally identical: // // { { { npipe | } npipe | } npipe | } npipe // // ( Note that we could also group from right-to-left. ) One way to // implement this is to have the child redirect stdin to a pipe while // the parent redirects stdout to a pipe. // Note: // o All msgs go to stderr // o The role of the parent and child can be switched. // // --| constants |-- const int CHUNK = 10; // --| prototypes |-- void getArgs(int argc, char *argv[]); int do_io(int which); // read (write) from (to) stdin (stdout); // return #bytes written to stdout int do_plumbing(int n); // setup n pipes; return which child int do_plumbing_alt(int n); // alternate algorithm // --| command line args |-- int N = 3; // -n N int alt = 0; // -a (alternate algorithm where pipes are created // first then assigned to processes) // --| other global variables |-- int fd[2]; // pipe fd int nbytes; // #bytes read unsigned int byte_sum; // sum of all bytes // --| inline functions |-- static inline void pipe_stdout(int fd[]) { Dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); } static inline void pipe_stdin(int fd[]) { Dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); } static inline void sum_bytes (char buf[], int n) { // sum up bytes in buffer for (int i=0; i 0) { DEBUG( (stderr, "++ pid = %d, rc = %d, CHUNK = %d\n", getpid(), n, CHUNK) ); nbytes += n; sum_bytes(buf,n); Write(STDOUT_FILENO, buf, n); } DEBUG( (stderr, "++ pid = %d: do_io out of loop with nbytes = %d, byte_sum = %d\n", getpid(), nbytes, byte_sum) ); if (which < (N-1)) close(STDOUT_FILENO); // or let exit handle return nbytes; }