This homework is due on Tuesday, March 8, at 11:59:59 PM (Eastern standard time). You must use submit to turn in your homework like so: submit cs421_jtang hw3 hw3.c
Your program must be named hw3.c, and it will be compiled on Ubuntu 14.04 as follows:
gcc --std=c99 -Wall -O2 -pthread -o hw3 hw3.cThere must not be any compilation warnings in your submission; warnings will result in grading penalties. In addition, your code must be properly indented and have a file header comment, as described on the coding conventions page.
In this homework, you are a programmer for the SuperDuperUber ride-sharing company. In town are several hotels popular with college students on Spring Break. Students summon rides to take them from one hotel to another; it is your responsibility to process the ride requests as quickly as possible. You have at your disposable a set number of cars to handle all of the requests.
Your C program must accept three command-line arguments: number of cars available, name of a data file, and a random seed:
The general flow for your program must be:
srand()
with the
seed specified by the last command-line parameter to seed the
PRNG.
The SuperDuperUber company has a fleet of cars to handle ride requests. Your program spawns a number of threads, based upon the command line, for each car.
For this assignment, you are to implement the classic producer/consumer model. The main thread will be the producer. Its job is to parse the data file and generate requests. The newly created threads are consumers; they handle the requests. Tying everything together is a common request pool. This pool is a global data structure that can hold an arbitrary number of requests. Note that there is no maximum size for the pool, hence your code must employ dynamic memory allocation.
When the main thread adds a request to the pool, it signals to the car threads. An idle car thread takes the first available request, while the other threads remain sleeping. Each thread handles a request independently.
A request consists of four parts: source hotel, destination hotel, number of passengers, and travel time. The car thread subtracts the number of people from the source hotel, pauses for a bit, then adds that number to the destination hotel. If there are insufficient number of people at the source hotel, the request must be deferred. The car thread must place the request back in the request pool and try a different request (if any).
Each thread must track the number of passengers it transported and how long it spent travelling (not sleeping). Prior to terminating, display these statistics.
In your code, add a comment block describing how you designed the request pool. Specifically, describe the mechanism(s) you employed to prevent race conditions in global data, and how the main thread notifies car threads when no further requests exist.
The data file format is as follows:
fgets()
to
read each line from the file.
Within your Ubuntu VM, use the wget command to fetch the data file http://www.csee.umbc.edu/~jtang/cs421.s16/homework/spring_break.data. The grader will use a different data file during grading. You may not make any assumptions about the number of hotels or requests, other than that there will be at least one of each. Furthermore, you may assume that all requests can be satisfied, though not necessarily in the order presented in the data file.
So as to ensure uniform results, at startup initialize the PRNG using the value given as the final command-line parameter.
When the main thread parses a request line, it needs to determine the actual travel time. Calculate this time as follows:
rand()
% D
.
When a car thread is handling a request, it first subtracts the
passengers from the source hotel. Next, the thread sleeps
for T milliseconds. Use nanosleep()
or usleep()
(your choice) to suspend the thread. Then
increment the destination hotel by the number of passengers.
Here is a sample output from running the program. This program has added extra debugging output, including which car thread is handling which request.
$ ./hw3 5 spring_break.data 421 Number of hotels: 6 Initial hotel counts: Hotel 0: 11 Hotel 1: 10 Hotel 2: 15 Hotel 3: 12 Hotel 4: 0 Hotel 5: 7 Thread 1: Taking 6 from hotel 1 to hotel 0 (time 898 ms) Thread 0: Taking 3 from hotel 2 to hotel 3 (time 184 ms) Thread 2: Taking 2 from hotel 2 to hotel 1 (time 413 ms) Thread 3: Taking 6 from hotel 0 to hotel 1 (time 1561 ms) Thread 4: Taking 7 from hotel 5 to hotel 3 (time 389 ms) Thread 0: Taking 5 from hotel 2 to hotel 4 (time 353 ms) Thread 4: Taking 3 from hotel 2 to hotel 5 (time 5176 ms) Thread 2: Taking 2 from hotel 2 to hotel 1 (time 537 ms) Thread 0: Taking 15 from hotel 3 to hotel 4 (time 2272 ms) Thread 1: Taking 6 from hotel 3 to hotel 0 (time 283 ms) Thread 3 took 6 passengers, for 1561 ms Thread 0: Taking 6 from hotel 4 to hotel 5 (time 4961 ms) Thread 2 took 4 passengers, for 950 ms Thread 1 took 12 passengers, for 1181 ms Thread 4 took 10 passengers, for 5565 ms Thread 0 took 29 passengers, for 7770 ms After all requests: Hotel 0: 17 Hotel 1: 14 Hotel 2: 0 Hotel 3: 1 Hotel 4: 14 Hotel 5: 9
For this assignment, you have the choice of using mutex locks and/or semaphores for thread synchronization. As an added challenge, you may earn an additional 10% on this assignment by using both synchronization techniques.
In hw3.c, implement the code using only mutex locks and/or condition variables. Then create the file hw3-alt.c, that is like hw3.c in all respects, but instead has only semaphores. Then submit both code files.
If you choose to perform this extra credit, put a comment at the top of both files, alerting the grader.