Everyone:

For the past couple of weeks, we have studied how an operating system virtualizes the CPU by providing processes and scheduling policies. By enabling users to execute multiple jobs simultaneously, the OS enables better utilization of the hardware and allows for more sophisticated workflows. Unfortunately, this multiprogramming ability comes with the cost of complexity due to issues related to concurrency.

Last week, we briefly examined event-based programming as an approach to implementing concurrency within a single process. Unfortunately, we saw that there are limits to this approach, and so this week, we will introduce pthreads as an alternative method of implementing concurrency. Afterwards, we will further explore how to tackle the challenges of thread-based concurrency with tools such as locks, condition variables, and semaphores.

TL;DR

For this reading assignment, you are to read about how to implement concurrency using threads and locks, submit your responses to the Reading 04 Quiz, and then modify your Reading 03 program to use pthreads.

Reading

The readings for this week are:

  1. Operating Systems: Three Easy Pieces

    1. Dialogue
    2. Concurrency and Threads
    3. Thread API
    4. Locks
    5. Event-based Concurrency

Optional Readings

  1. On the duality of operating system structures

  2. Async IO on Linux: select, poll, and epoll

Quiz

Once you have done the readings, answer the following Reading 04 Quiz questions:

Program

For this week's program, you are to modify the program.c from Reading 03 such that you use separate threads instead of processes to compute the SHA1 digest for each argument. In other words, for each file argument, you need to create a thread that computes and displays the SHA1 digest of the contents of the file. The main thread should collect the exit statuses of its worker threads and return 0 if all the threads were successful. Otherwise, it should return the number of threads that failed as its own exit status.

Example

The usage and output of your program should be the same as sha1sum:

$ ./program Makefile  # Compute SHA1 of Makefile
50bb7f7ccf1ca089f3c5eaff5fe95e56ddbe53a5  Makefile

$ echo $?             # Check exit status
0

$ ./program asdf      # Handle invalid files

$ echo $?             # Check exit status
1

Requirements

Note: To link properly to the SHA1 functions, you will need to add -lcrypto to the LIBS variable in your Makefile. You will also need to add the -pthread flags to your CFLAGS.

Hints

You should not need to modify your original sha1sum_file function from Reading 03. Instead, you should convert your existing sha1sum_process function into a similar sha1sum_thread function:

void *sha1sum_thread(void *arg) {
    char *path = (char *)arg;
    ...
    if (!sha1sum_file(path, cksum)) {
        ...   // Failure
    }
    ...       // Success
}

Once you have a sha1sum_thread function, you will need to modify the main function as follows:

function main():
    pthread_t thread[argc - 1]  # Thread array

    For each argument:
        Create a thread stored in thread[i] that runs sha1sum_thread

    For each thread in thread array:
        Join thread[i]
        Update the overall program status

Submission

To submit you work, follow the same process outlined in Reading 01:

$ git switch master                   # Make sure we are in master branch

$ git pull --rebase                   # Make sure we are up-to-date with GitHub

$ git checkout -b reading04           # Create reading04 branch and check it out

$ cd reading04                        # Go into reading04 folder
$ $EDITOR answers.json                # Edit your answers.json file

$ ../.scripts/check.py                # Check reading04 quiz
Checking reading04 quiz ...
      Q1 0.25
      Q2 0.15
      Q3 0.40
      Q4 0.15
      Q5 0.20
      Q6 0.15
      Q7 0.25
      Q8 0.15
      Q9 0.30
   Score 2.00 / 2.00
  Status Success

$ git add answers.json                # Add answers.json to staging area
$ git commit -m "Reading 04: Quiz"    # Commit work

$ $EDITOR program.c                   # Edit your program.c file

$ make test-program                   # Check reading04 program
Testing reading04 program ...
 I/O System Calls                                             ... Success
 I/O Functions                                                ... Success
 Memory Functions                                             ... Success
 SHA1 Functions                                               ... Success
 Process System Calls                                         ... Success
 Thread Functions                                             ... Success
 program                                                      ... Success
 program (valgrind)                                           ... Success
 program Makefile                                             ... Success
 program Makefile (valgrind)                                  ... Success
 program Makefile (strace)                                    ... Success
 program Makefile README.md                                   ... Success
 program Makefile README.md (valgrind)                        ... Success
 program Makefile README.md (strace)                          ... Success
 program Makefile README.md program.c                         ... Success
 program Makefile README.md program.c (valgrind)              ... Success
 program Makefile README.md program.c (strace)                ... Success
 program Makefile README.md program.c asdf                    ... Success
 program Makefile README.md program.c asdf (valgrind)         ... Success
 program Makefile README.md program.c asdf (strace)           ... Success
 program Makefile fdsa README.md program.c asdf               ... Success
 program Makefile fdsa README.md program.c asdf (valgrind)    ... Success
 program Makefile fdsa README.md program.c asdf (strace)      ... Success
 program Makefile README.md /bin/ls /bin/bash                 ... Success
 program Makefile README.md /bin/ls /bin/bash (valgrind)      ... Success
 program Makefile README.md /bin/ls /bin/bash (strace)        ... Success
   Score 2.00 / 2.00
  Status Success

$ git add program.c                   # Add program.c to staging area
$ git add Makefile                    # Add Makefile to staging area
$ git commit -m "Reading 04: Code"    # Commit work

$ git push -u origin reading04        # Push branch to GitHub

Pull Request

Once you have committed your work and pushed it to GitHub, remember to create a pull request and assign it to the appropriate teaching assistant from the Reading 04 TA List.