Assignment 5: D pipeline

Due: 5:00pm, Friday, November 1. Value: 60 pts.

A common pattern for concurrency is the pipeline, where the problem can be broken down into a series of stages, each processing the output of the previous one. Such a structure obviously arises from the Unix command line, but another prominent example of the pipeline comes from a compiler, where each stage of the compiler translates the program into from one representation to another that is closer to machine code.

In this assignment, we'll use D's message passing facility to simulate a Unix shell. You will need two files.

mysh.d Includes main that reads and parses commands from the user, as well as functions corresponding to a variety of Unix commands. You will not modify this file.
pipeline.d This is the file you will modify. Its execute function should create a threads to execute each of a series of commands, and it should use message passing so that the output of one command is the input to the next one. (Do not use shared memory, such as the shared keyword.)

You can start the program using the command “rdmd mysh.d”. The provided code provides partial implementations for the Unix cat, cut, grep, head, sort, and uniq commands. In fact, it implements everything (except for output redirection — the > operator) in the first 9 sections of “Introducing the Linux command line”, which you probably read as you worked on Assignment 1 from Computing Systems Organization.

In pipeline.d, your implementation will be divided roughly into two pieces.

  • In execute, you'll want to create a thread for each command, where each thread is aware of the following thread's ID (tid), except the last command would be aware of the thread executing execute. After creating the threads, execute would then simply receive messages from the final command and echo it to the screen.

  • In the Pipe class, you'll need to provide implementations of readln, writeln, and close; these are methods that are used by the functions resembly Unix commands. Essentially, writeln and close will send a message to the following thread in the pipeline, whereas readln will receive a message from the preceding thread in the pipeline. Note that readln takes a ref bool parameter, which should be set to true once it receives a message that the preceding thread has invoked close.