The Arm Wrestler Problem

See Shared Memory and Semaphores for a description of how to obtain and use shared memory and semaphores in Unix.

Your code is to be written in C

Problem Description

The State fair features an arm wrestler. Any patron who can beat the arm wrestler will be paid $25. Losers pay the arm wrestler $10. The arm wrestler requires absolute silence in order to concentrate fully on beating opponents. Therefore, the arm wrestler has a tent secluded from the rest of the fair. The arm wrestler can only compete with one patron at a time. Patrons wishing to compete are first admitted to a special waiting room outside the arm wrestler's tent. When the arm wrestler finishes with a patron, another patron is admitted to the arm wrestler's tent from the waiting room. The waiting room has a finite capacity of size n. If the waiting room is full, a Patrons wishing to wrestle walks around the fair and then checks back. Since arm wrestling is somewhat strenuous, if there are no patrons, the arm wrestler falls asleep. A patron arriving while the arm wrestler is asleep must wake the arm wrestler. Since the arm wrestler does not want to overuse the wrestling arm, the arm wrestler places a limit on the number of daily matches. Patrons in the waiting room after the daily limit has been reached or arriving after are turned away.

Implementation Details

Limits

Your arm wrestler will limit the total number of competitions to n= 20. The capacity of the waiting room is 3. These values must be declared as constants or #define so they can be changed easily.

Winnings

You are going to use a random number generator to determine the outcome of each wrestling match. Use srand() to seed the random number generator and rand to generate the random number. Your main process will call srand() once to seed the random number generator. It should be seeded with the the pid of the main process so that a different set of random numbers is always generated.

Your Main Program/Process

Your program should first obtain and initialize any shared memory and semaphores required to coordinate the arm wrestler and the fair patrons.

Your main process should then seed the random number generator:

srand (getpid());

Your program should then fork. The child of this first fork is to become the arm wrestler. The parent should then fork 5 more children. These five children are to become patron processes.

After all of the children have been forked, your main process must wait for all children to terminate. After all children have terminated, your main process should display the results of wrestling: The $ the wrestler earned and the $ earned by patrons. After displaying the results of the day, the main process should return all shared memory and semaphores and terminate.

Shared Memory

At a minimum, you will need shared memory for the following:

You may need additional memory, depending on your implementation.

You must define constants to index memory for each of the shared memory values. This will greatly improve readability and decrease the chances of programming errors.

Semaphores

You will need semaphores for the following:

It is important that the semaphores are properly initialized to control synchronization between the wrestler and patrons and that shared memory is only accessed by one process at a time.

Arm Wrestler

If there are no patrons, go to sleep. This implies shared memory indicating how many patrons are currently waiting and mutual exclusive protection for that shared memory. When a patron arrives into the waiting room, "admit" the patron to the wrestling room. The patron and wrestler must "synchronise", each printing a message wrestling in progress, identifying if it is a patron or the wrestler. The "admit" will require some protocol between patrons and arm wrestler.

At the conclusion of each wrestling match, the wrestler process uses rand() to determine the outcome of the match. If the random number generated is:

Be sure to test your program to ensure you always get a different set of random numbers.

The wrestler must appropriately update shared memory, $25 to the patrons' winnings if the random number is divisible by 4 or $10 to the wrestler's winnings if not divisible by 4.

This process of admitting and wrestling while there are patrons or wrestler sleeping if no patrons continues until the arm wrestler has wrestled with 20 patrons. The arm wrestler then sets status that the arm wrestling tent is closed and must "force" all patrons in the waiting room to terminate. The arm wrestler then terminates. Closed status will be shared by many processes. As stated above, access to it must be done with mutual exclusion.

 

ArmWrestler()

{

while number of wrestling matches <=20

{

sleep while no patrons

decrement number of patrons waiting

admit patron to wrestling tent

wrestle

decrement matches remaining

update winnings

}

Set closed status

Wake up patrons in the waiting room

terminate

}

Patron Processes

Upon creation, patron tests to see if arm wrestler has terminated. If arm wrestler has terminated, patron should terminate. Otherwise, patron should begin a loop trying to get into the waiting room. On entry to the waiting room, a message should be printed including the process id of the patron, patron should indicate it is waiting, wake up the wrestler if necessary, then wait to be admitted to the wrestler's tent to wrestle. When admitted to the tent, synchronize with the wrestler and print message wrestling along with the PID of the wrestling patron. The patron's wrestling message and the wrestler's wrestling message should appear together in the output.

Patron continues to loop entering waiting room and wrestling until the arm wrestler closes.

 

Patron()

{

do while not closed

{

Keep trying to enter the waiting room. Once entered:

notify wrestler a patron is available

increment number of patrons waiting

wait to wrestle

wrestle

}

terminate

}

Be careful, wrestler could close after being admitted to the waiting room.

Hints

Remember!!!! , you must execute fflush(stdout) after every printf in order to flush the buffer. The OS buffers the output of each process. If you do not flush the buffer, you will not see the output as it actually occurs.

You should run your program MANY times. You should try running it from different configurations and at different times of the day.

Remember to clean up after yourself if your program crashes. Semaphores and shared memory or permanent. The system may run out. If someone in the class runs the system out of shared memory and semaphores and no one can work on their programs or submit their programs, everyone suffers; there will not be an extension

Submission

  1. Use turnin to submit your program. Select CS326, wrestler. Your code must be in the source file wrestling.c.

    Your well structured, commented, correctly executing code (80%). It is acceptable to look in text books for similar problems to assist you in developing your solution. You are encouraged to do so. If you find a similar problem and base your solution on its solution, be sure to site the reference in your header comments.

  2. Using a word processor (hand this report in class), write a report discussing the following (20%):
    1. For each shared variable and semaphore, describe how it is used and present an argument as to why it is needed (why the solution would not work without it).
    2. Present an argument that your solution preserves mutual exclusive access to any shared variables. This may be addressed in the previous section. If so, be very specific.
    3. Present an argument that your solution does not deadlock. For each of the two types of processes, each time they wait on some type of event, demonstrate that they will eventually come alive.

A formal proof is not required. However, your arguments must be clear, concise, and valid. For example, just stating that the patron has mutual exclusive access to the closed variable because it waits on a semaphore before accessing it is not sufficient. You must address all places where closed status is accessed and argue that no other process will simultaneously access it.



Last modified: 11/10/2024
This lab is © copyright protected by Barbara Bracken