HW2: Signals & Threads

CS 321 Homework, Dr. Lawlor, 2006/02/03.  Due Friday, February 10 at 5pm.

Here's a series of problems regarding the handling of signals and threads.  You're expected to turn in the result of each problem to Blackboard, by clicking on "Assignments", "View/Complete Assignment", attaching your files, and clicking "Submit" (be careful!  "Save" isn't the same as "Submit"!).

UPDATE: People using Visual C++ may have a hard time getting the #include "osl/porthread.h" inside osl/porthread.cpp to work.  On the command line, you can fix this by just adding the argument "/I.". In the Visual C++ GUI, you can either change the Visual C++ "include file path" to point to your directory, or edit osl/porthread.cpp to say #include "porthread.h" (without the "osl/" directory).

Download all the source code files for this assignment: (Directory, Zip, Tar-gzip)
  1. The program problem1.cpp starts up two threads, but exits before the threads finish.  Change the program so both threads actually finish running.  You can modify any routine you like, but both threads MUST still be threads, and both threads MUST finish before exiting.
  2. The hardware control program problem2.cpp has a serious bug--halfway through accessing the hardware, it crashes while leaving the hardware running.  Change the "setup" routine so it turns the hardware off using the "turn_off_hardware" routine when a divide-by-zero (SIGFPE) crash occurs.  You CANNOT change the run_hardware routine!
  3. The program problem3.cpp has the same problem as problem 1--first, the threads don't actually run.  Fix this problem, and then you'll see the "do_work" routine's printouts get messed up when the kernel switches between threads, like this:
    a0,            b0,B0
    b1,B1
    A0
    a1,A1
    a2,A2
    ...
    Change thread_routine so that each call to "do_work" is atomic, in the sense that no two threads will run do_work simultaniously, and the printouts from one execution of do_work should appear together, like this:
    a0,A0
    b0,B0
    b1,B1
    a1,A1
    a2,A2
    ...
    You CANNOT change the "do_work" routine.

Open-Ended Problems

Half your homework grade is to complete any five open-ended problems (miniprojects) throughout the semester.  I'll try to offer at least one open-ended problem with each week's homework.  If you complete more than five open-ended problems through the semester, I'll take the five with the highest grades. 

Turn in open-ended problems by naming the source code "problem.s" and submitting it on blackboard as HW2_O.  HW2_O is due Friday, February 17 at 5pm.
  1. Write any program that *recovers* from a SIGSEGV, SIGILL, or SIGFPE signal--that is, it takes the signal, but then returns from the signal handler in such a way as to finish executing.  An infinite loop is really easy to write, but doesn't count.  Using "kill" to send yourself a bogus signal is also easy, but doesn't count.  SIGSEGV can be recovered from using mmap(), or using setjmp/longjmp and global variables to fix the accessed address.  SIGILL can be recovered from by modifying the offending instruction in memory at runtime.  SIGFPE can be recovered from using setjmp/longjmp to fix the source of the error.
  2. Write any *correct* implementation of locks yourself, for any threading package.  You may use any routines except pthread_mutex_lock or EnterCriticalSection.  Check out the x86 lock instruction prefix, which is directly supported by NASM and gcc.