Project 2 - User-Level Threads

Project Subpart description links

Part 1 Out: Sunday, January 26, 2003
Part 1 Scheduler Design Doc Due: Thursday, January 30, 2003
Part 1 Implementation Due: Friday, February 7, 2003

Part 2 Out: Monday, February 17, 2003
Part 2 Due: Friday, February 28, 2003 Monday, March 3, 2003

Tasks:
  1. Design and implement a preemptive user-level thread manager.
  2. Add a set of common synchronization primitives to your thread package.
  3. Implement a multithreaded web-server and other tests to test your thread package.
  4. Analyze your design and test results in a report.

Updates:


Assignment Goals


Background

In the beginning (well, the relative beginning), there was UNIX. UNIX supported multiprogramming; that is, there could be multiple independent processes each running with a single thread of control.

As new applications were developed, programmers increasingly desired multiple threads of control within a single process so they could all access common data. For example, databases might be able to process several queries at the same time, all using the same data. Sometimes, they used multiple processes to get this effect, but it was difficult to share data between processes (which is typically viewed as advantage, since it provides isolation, but here it was a problem).

What they wanted was multithreading support: the ability to run several threads of control within a single address space, all able to access the same memory (because they all have the same mapping function). The programmers realized that they could implement this entirely in the user-level, without modifying the kernel at all, if they were clever.

A single UNIX process will be allocated some amount of CPU time with which it is free to do just about anything. If it has 2 threads inside of it, it can split the time between them. The kernel doesn't have to know anything about this process; to it, the process appears like any other.

As you'll discover in the last part of this assignment, there were some problems with this approach, which motivated kernel developers to include thread support in the kernel itself (and motivated researchers to do it better; see Scheduler Activations).


Simplethreads

You will be using the simplethreads-preemptive package for this assignment. It is available on spinlock/coredump in /cse451/projects/simplethreads-preemptive-1.X.tar.gz (Where X is the release number number, which may be updated. Use the latest version. Please watch for updates as the project progresses.)

This project, since it does not involve modifying the kernel, does not require VMWare. The simplethreads package should work on any Linux 2.4 machine (it will not work on Linux 2.2 due to missing support for a necessary syscall), and other varieties of UNIX that support pthreads as well. (Please do not use tahiti, fiji, ceylon, or sumatra.) It will not work with Cygwin. It has been reported to work with Mac OS X v10.1, but this has not been tested. Also the behavior of pthreads is different on Linux 2.4 in comparison to most other unicies; in Linux 2.4 with glibc >2.0, pthreads are kernel threads. Please do not run test involving pthreads with another unix variant.

To begin, copy that file to your work directory and run
tar xvzf simplethreads-preemptive-1.X.tar.gz
to expand it (if you are working on a different machine, see scp(1)).

Simplethreads contains a lot of files, but most are safe to ignore. Pay attention to:
Dir/File Contents
lib/ The simplethreads thread library itself.
lib/sthread_user.c Your part 1 and part 2 implementations go here.
lib/sthread_ctx.h Support for creating new stacks and switching between them.
lib/sthread_queue.h A simple queue that you may find useful.
lib/atomic.h An atomic type and functions that manipulate that type
include/ Contains sthread.h, the public API to the library
(the functions available for apps using the library).
test/ Test programs for the library.
web/ The multithreaded webserver for part 3.

Like many UNIX programs, simplethreads uses a configure script to determine parameters of the machine needed for compilation (in fact, you'll find many UNIX packages follow exactly the same steps as simplethreads for compilation). In the simplethreads-preemptive-1.X directory, run ./configure to test all these parameters.

Finally, build the package by typing make. You can also build an individual part, such as the library, by running make in a subdirectory. Or, if you just want to compile one file, run make myfile.o (from within the directory containing myfile.c).

Note that, as you make changes, it is only necessary to repeat the last step (make).

One interesting feature of simplethreads is that applications built using it can use either the native, kernel-provided threads or the user-level threads that you'll implement. When running the test programs, use --sthread-pthread to select kernel threads or --sthread-user to select user threads (they default to kernel threads).

In summary, the steps are:

  1. Copy the tar.gz source to your directory.
  2. tar -xvzf simplethreads-preemptive-1.X.tar.gz
  3. cd simplethreads-preemptive-1.X
  4. ./configure
  5. make
  6. Run the programs in test/

To Add a Source File

If you add a new source file, do the following:
  1. Edit the Makefile.am in the directory containing the new file, adding it to the _SOURCES for the library/executable the file is a part of. E.g., to add a new file in the lib/ directory that will become part of the sthread library, add it to the libsthread_la_SOURCES line.
  2. From the top-level directory (simplethreads-preemptive-1.X), run automake.
  3. Also from the top-level directory, run ./configure.
  4. Your file is now added; run make as usual to build it.

To Add a New Test Program

  1. Edit test/Makefile.am. Add your program to the list bin_PROGRAMS. Create new variables prog_SOURCES and prog_LDADD following the examples of the programs already there. For example, if the new program is named test-silly, add:
    test_silly_SOURCES = test-silly.c other sources here
    test_silly_LDADD = $(ldadd)
  2. Follow steps 2-4 above.