CMSC 421: Principles of Operating Systems

Homework 3: Game of Loans

This homework is due on Monday, October 12, at 11:59:59 PM (Eastern daylight 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.c
There 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 October of both 1929 and 1987, the U.S. stock market had historic crashes. In honor of those events, you will write a computer program that simulates stock trading among several investors. The program will need to parse a file containing information about stock traders, stock funds, and pending stock transactions. Next, the program will perform those transactions, reordering the transactions as necessary. The goal is to complete all transactions as quickly as possible.

Part 1: Starting Up

Your C program must accept two command-line arguments: the name of a data file and a random seed:

At startup, perform these actions:
  1. Parse the given data file given by the first parameter on the command-line.
  2. Initialize all stock funds with the amount given in the data file.
  3. Initialize the pseudo-random number generator, by calling srand() with the seed specified by the second command-line parameter.

Part 2: Data File Format

The data file format is as follows:

Within your Ubuntu VM, use the wget command to fetch the data file http://www.csee.umbc.edu/~jtang/cs421.f15/homework/hw3.data. The grader will use a different data file during grading. You may not make any assumptions about the values S, F, or T other than that they will be within the ranges as stated above.

Part 3: Threading

After initialization, your program will simulate stock transactions. Spawn S number threads, one for each stock trader. Each thread handles a transaction independently.

For a transaction, subtract the amount to transfer from the source fund. Then pause for a random amount of time (see Part 4). Complete the transaction by incrementing the target fund by the amount transferred.

As proof that your program has correctly handled all transactions, display all funds' amounts afterwards.

In your code, add a comment block describing the scheduling algorithm your program implemented. Specifically, describe how the program decides the order to perform the transactions and how it decides which thread to handle the transaction.

Part 4: Pausing and Getting Random Numbers Safely

So as to ensure uniform results, at startup initialize the pseudo-random number generator using the value given as the second command-line parameter.

In between subtracting from the source and adding to the destination, the thread must pause for a non-deterministic time. Use the sleep() function to temporarily suspend the thread. The parameter to sleep() is an amount of time, in seconds. To make this assignment more interesting (and challenging), your code must perform as follows:

  1. Determine the time to sleep randomly. Let A equal to rand() % r, where r is the amount of time required for a given transaction. The call sleep(A).
  2. The rand() function is not thread-safe. That means all calls to it must be protected by a lock.
  3. The code may not pre-calculate how long to sleep. That is, the program must not calculate A, when determining the order to process transactions or when determining which thread to handle the transaction. Instead, a thread may only calculate A just prior to calling sleep().

Sample Output

Here is a sample output from running the program. This program has added extra debugging output, including which stock trader is handling which transaction.

$ ./hw3 hw3.data 421
Number of stock traders: 4
Number of stock funds: 6
Number of transactions: 11
Initial amounts:
  Fund 0: 10
  Fund 1: 15
  Fund 2: 12
  Fund 3: 0
  Fund 4: 7
  Fund 5: 5
Trader 0: Transaction #0: Moving 6 from fund 1 to 0 (reqired time 5, actual 0)
Trader 0: Transaction #1: Moving 3 from fund 2 to 3 (reqired time 7, actual 0)
Trader 1: Transaction #2: Moving 6 from fund 4 to 5 (reqired time 8, actual 5)
Trader 2: Transaction #3: Moving 2 from fund 2 to 1 (reqired time 4, actual 2)
Trader 0: Transaction #4: Moving 6 from fund 0 to 1 (reqired time 1, actual 0)
Trader 0: Transaction #5: Moving 7 from fund 5 to 3 (reqired time 6, actual 5)
Trader 3: Transaction #6: Moving 5 from fund 2 to 4 (reqired time 2, actual 0)
Trader 3: Transaction #7: Moving 3 from fund 2 to 5 (reqired time 6, actual 2)
Trader 2: Transaction #8: Moving 2 from fund 2 to 1 (reqired time 7, actual 5)
Trader 1: Transaction #9: Moving 15 from fund 0 to 2 (reqired time 9, actual 7)
Trader 2: Transaction #10: Moving 6 from fund 3 to 0 (reqired time 4, actual 3)
After all transactions:
Fund 0: 1
Fund 1: 19
Fund 2: 12
Fund 3: 4
Fund 4: 6
Fund 5: 7

Other Hints and Notes

Extra Credit

A simple implementation will take 22 seconds to complete hw3.data with the random seed 421. As a friendly competition, and for fame and glory, you may optimize your scheduling algorithm. You may earn an additional 10% on this assignment if your program can consistently beat the instructor's reference implementation given a different data file and random seed. Furthermore, the fastest submission for the entire class will gain another 5% (for a total of 15%).

Each students' submission will be timed via the time command, like so:

$ time ./hw3 some_data_file.dat some_unknown_seed
...
real    0m22.004s
user    0m19.824s
sys     0m15.940s

Your implementation may not cheat, including but not limited to:

The instructor is the final arbitrator of what is considered cheating or not.

If you choose to perform this extra credit, put a comment at the top of your file, alerting the grader.