Assignment 12: Mutually Exclusive

Due Friday, April 18th, before midnight

The goals for this assignment are:

  • Synchronize the behavior of multiple threads

  • Work with mutex and condition variables

Update your repository

Do a fetch upstream to obtain the basecode for this assignment.

Using the command line

  • Open terminal and change your current directory to your assignment repository.

  • Run the command git fetch upstream

  • Run the command git merge upstream/main

Your repository should now contain a new folder named A12.

The fetch and merge commands update your repository with any changes from the original.

1. Consumer/Producer

In the file, cp.c, implement the producer/consumer demo from class. Your producer function should generate an integer between 0 and 9. Your consumer function should print the value. The size of your circular queue should be 10 elements.

$ ./cp
Received item: 3
Received item: 6
Received item: 7
Received item: 5
Received item: 3
Received item: 5
^C

Requirements:

  • Use sleep(1.0) to slow the production of values and make the output of your program easier to read.

  • Place the behavior of both threads in an infinite loop. Use Control-C to exit your demo.

2. Banking

Edit the file, banking.c, so it correctly handles a series of transfers between two accounts. Specifically, you should ensure

  • The program does not subtract funds if there aren’t sufficient funds in the account.

  • The program does not hang due to deadlock

When you run the basecode, you will see the following behavior.

$ ./banking
Starting balance A: 5000.00
Starting balance B: 5000.00
banking: banking.c:29: Transfer: Assertion `fromAcct->balance >= 0' failed.
Aborted (core dumped)

Add a mutex and condition variable to each account. This variable can be used to ensure that we do not subtract funds unless there is enough money in the account. Use the consumer/producer demo in the previous question as an example. Also make sure that your mutexes avoid deadlock as well. A working program should look at follows.

$ ./banking
Starting balance A: 5000.00
Starting balance B: 5000.00
Ending balance A: 5000.00
Ending balance B: 5000.00

Requirements:

  • Do not remove the assert in your code. A working program will not trigger the assert.

  • Use a condition variable to enforce whether an account has sufficient funds

3. Bridge

In the remote town of Mountainview Village, there is a single lane bridge that connects a popular overlook with a quaint town center with shops and cafes. During peak season, tourists spend the day driving back and forth across the bridge, alternating between fresh air and inspiring views at the outlook platform and coffee, ice cream, and snacks at the town center.

In the file, bridge.c, your will find a simulation of summer tourists. Each tourist is simulated with a thread. The bridge is modeled as a shared, global resource. If two cars simultaneously try to drive in opposite directions on the bridge, we have a terrible accident. The bridge explodes and any cars on the bridge plummet to the rapids below.

Edit the file, bridge.c, to safely simulate N tourists spending the day in Mountainview Village.

  • prevent deadlocks where no one takes the bridge

  • prevent accidents where cars travel in both directions at once

For example, here is a single tourist.

$ ./bridge 1 10
Tourist 0 takes their 0/10 trip towards Outlook
Tourist 0 takes their 1/10 trip towards Town
Tourist 0 takes their 2/10 trip towards Outlook
Tourist 0 takes their 3/10 trip towards Town
Tourist 0 takes their 4/10 trip towards Outlook
Tourist 0 takes their 5/10 trip towards Town
Tourist 0 takes their 6/10 trip towards Outlook
Tourist 0 takes their 7/10 trip towards Town
Tourist 0 takes their 8/10 trip towards Outlook
Tourist 0 takes their 9/10 trip towards Town

But running with multiple tourists, we quickly see a problem.

$ ./bridge 2 10
Tourist 1 takes their 0/10 trip towards Town
Tourist 0 takes their 0/10 trip towards Outlook
bridge: bridge.c:38: Move: Assertion `bridge.num_on_bridge[(bridge.direction+1)%2] == 0' failed.
bridge: bridge.c:38: Move: Assertion `bridge.num_on_bridge[(bridge.direction+1)%2] == 0' failed.
Aborted (core dumped)

Requirements:

  • Your program must leave the asserts which verify that the safety constraints are enforced.

  • You should use conditional variables and mutex to synchronize the threads that represent each tourist.

4. Submit your work

Submit both your code and images.

1) Push your code work to github

$ git status
$ git add .
$ git status
$ git commit -m "assignment complete"
$ git status
$ git push
$ git status

5. Grading Rubric

Assignment rubrics

Grades are out of 4 points.

  • (1 points) Consumer/Producer

  • (1 points) Banking

  • (2 points) Bridge

Code rubrics

For full credit, your C programs must be feature-complete, robust (e.g. run without memory errors or crashing) and have good style.

  • Some credit lost for missing features or bugs, depending on severity of error

  • -5% for style errors. See the class coding style here.

  • -50% for memory errors

  • -100% for failure to checkin work to Github

  • -100% for failure to compile on linux using make