CS 110, Architecture and Operating Systems
Basic Barbershop Project
Version 1.00
35 Points

Due April 19th, 2002, at 9 PM


Each of you is to implement a robust version of the Barber Shop problem using the UNIX fork command and mutual exclusion techniques (use your partner for design and code review). This barbershop is on a military base, so there are 3 categories of people needing haircuts - officers, NonComs, and grunts. You are to use a producer/consumer paradigm with a shared circular buffer.

Mutual exclusion is to be provided by Solaris semaphores (see semctl). The shared buffer is to be provided by Solaris shared memory (see shmctl).


Your producer, a fat old Sergeant, is a process that periodically attempts to add a new person with long hair to the buffer of chairs in the barbershop. "Periodically" means that the producer uses the sleep function with a sleep time determined by a command line input parameter. The sleep time must be between 1 and 5 seconds, with a default of 3 seconds. If there are no open seats, then the Sergeant waits until there is an empty chair (note that in this case more than 5 seconds might elapse before the next person is seated).


The producer and consumer share a buffer of 20 chairs, but there are 3 FIFO lists within the 20 chairs. At any time there may be only 20 people in the barbershop chairs with a random distribution of Officers, NonComs, and Grunts, and 1 person getting a haircut. Note: if there is only one type of person in the barbershop, then the shop queue acts like a circular buffer.

The FIFO lists must be implemented as linked lists using integer indices as pointers.


Your consumer process is the Barber, a wiry old private. Haircuts have an individual time between 1 and 5 seconds, controlled by the input file (see below). The Barber gives priority for service: if there are any officers waiting, they get their haircuts first, even if a NonCom or grunt has been waiting longer; similarly, NonComs get priority over grunts.

Input File

The pattern of people arriving for haircuts is controlled by an input file, read from the standard input. The input is a series of 2-digit numbers that encode both the type of soldier and the time needed for a haircut:

For example, 01 indicates a grunt who needs a 1-second haircut, while 24 is an officer who needs 4 seconds.

You may assume that the input file consists exclusively of numbers, but you must make sure that the numbers are valid, rejecting illegal soldier types and invalid haircut times. The easiest way to process the input is to read a number and then separate the digits using integer division and the modulus operator.

Here is a sample input file that will not stress your program very much.


As in the Dining Philosophers project, the participants in the game are so busy doing things that they don't have a chance to figure out what is going on. Thus you MUST have another process, the Lieutenant, who monitors the overall barbershop. Because he is young and stupid, every 2 seconds the Lieutenant pokes his head into the barbershop to determine:

The Lieutenant numbers each output line sequentially (easier to watch the time fly).

Optionally (controlled by the second parameter to the program) the Lieutenant can also dump the contents of the three queues (everyone in the queue, their chair number, etc.).

A short example of the output should clarify some of these points. Your output must match the sample format exactly to make grading easier.

In the sample output, lines 1-6 of each group are what is normally printed out, while lines 7-10 are the additional lines produced if parameter 2 is nonzero. Note that the person in the chair with the lowest number is the next person of that category to have their hair cut. Also note how position numbers change as someone's hair is cut, i.e., in the first group (watch #20), the next NC is 18, in the second group (watch #21), the next NC is 17 (because the guy in 18 moved to the barber chair. Finally, note how there is only one entry in each column (since each array slot can only hold one type of person) and the grunt queue is not in any particular order.


The barbershop program must be invoked with three arguments:

  1. How long in seconds the consumer process should sleep before starting -- i.e., the time it takes the barber to have his coffee in the morning. This means that the producer (Sergeant) is running, but the consumer has not yet started. You can set this to a high value to find out how your barber and Sergeant deal with a full waiting list. Default = 1 second.
  2. Nonzero if the Lieutenant should dump the contents of the queues (lines 7-10). Default = 0, don't print.
  3. How long the producer should sleep between each search of the wait area (i.e., before reading each input line after the first). Default = 3 seconds.


When the input file is empty, the Sergeant terminates, but the barber continues until the last longhair has had his haircut. The Lieutenant continues until both the Sergeant and the Barber have terminated. Look at some of the semaphore operations for ways to do this. Thus, the final output from the Lieutenant should show an equal number of long hairs entering the system and short hairs produced, with an empty waiting room at the end.

Submission Instructions

Submit your code in the usual way, using cs110submit.

We will either test your program against other input cases, or ask you to demonstrate your program to the graders (procedure to be determined later).

Other Notes



We reserve the right to change the problem statement when someone demonstrates the ambiguity of said problem statement.

Last modified April 6, 2002 by geoff@cs.hmc.edu