CMPS 105: Systems Programming

Programming Assignment #6: Pseudo audio player

Due: Monday, May 31


Remember: your programming assignment must be turned in online.

The Basics

The goal of this assignment is to get familiar basic UNIX IPC.

In this assignment, you are to implement the skeleton of an audio player in which two processes communicate with shared memory and semaphores.

The program will create two processes or, alternatively, you may have two programs each of which is a single process. Process 1 will read text from a file and put it into buffers in a bounded buffer (an array of relatively small buffers). The second process will read the text out of the bounded buffer one buffer at a time and print it on the screen.

This is similar to how typical audio players work. mpg123 is a public domain audio player that works this way. The first process reads mp3 data from a file and decodes it and places the wav format data into a bounded buffer. The second process reads the decoded information and puts it into memory on the audio card, from which it is transformed into sound and played.


The Details

To implement your program, you will need to use the systems calls that create and attach to shared memory and semaphores. The shared memory will contain the bounded buffer and any shared variables. The semaphores will be used to coordinate the activities of the producer process and the consumer process so that the producer stops producing when all of the buffers are full and doesn't overwrite any buffers that haven't been emptied yet by the consumer, and so the consumer stops consuming when there is no data available and doesn't try to read data from an empty buffer.

A good way to deal with the shared memory is to define in a header file shared by the producer and the consumer a struct defining the data that will be contained in the shared memory. Then, create in both the producer and the consumer a pointer to that struct and assign to that pointer the value returned from the shmat() call. Now you can access the shared memory symbolically through that pointer.

My recommendation in class was to use two semaphores (call them A and B). A can be initialized to the number of buffers in the bounded buffer, and B can be initialized to 0. Whenever the producer goes to produce anything, it first waits on A. After is has produced something, it signals B. Similarly, before it consumes anything, the consumer waits on B. After it has consumed a buffer, it signals A. Each process (producer and consumer) will rotate through the buffers, and must keep an internal pointer to keep track of which buffer it should operate on next.

For extra credit (up to 10 points), you may actually implement an audio player or some other application that makes use of the bounded buffer. A very easy one (worth perhaps 2 points of extra credit) would be "more", where the consumer consumes and prints out one page each time the user enters a character. For an additional point of extra credit, you may explain what minor advantage this implementation of more might have over one that simply reads and displays (with one process) pages of the file, pausing before each read-and-display until a character is entered.

Note: You must check and correctly handle all return values. This means that you need to read the man pages for each function to figure out what the possible return values are, what errors they indicate, and what you must do when you get that error.


What to turn in

Your code, a working makefile, and your design document. In addition, include a README file to explain anything unusual to the TA — testing procedures, etc.

REMEMBER: Do not submit object files, assembler files, or executables. Every file in the submit directory that could be generated automatically by the compiler or assembler will result in a deduction from your programming assignment grade.


sbrandt@cse.ucsc.edu