CS 3733 Operating Systems, Spring 1996 Assignment 4

Read the entire assignment before starting. All output from the programs in this assignment should go to standard error. You must use a makefile for compilation. Turn in the makefile, the source code, lint output, and the output generated by your program.

Part I:

Do the license manager exercise described in Section 8.8 of PUP, up to but not including the last paragraph on page 327.

The runsim program should start by printing a message of the form:

This should be done before anything else.

You can get your user ID using getuid(). Your user ID should not be hard coded into the program.

Make sure you read the note about union semun on page 321.

Use the readline function in /usr/local/courses/cs3733/pup/ch08 to read in the line. If you use fgets you may run into a bug in the C library which could cause some lines to be read more than once.

Write functions semwait(int semid) and semsignal(int semid) which perform the classical semaphore operations but restart in case they are interrupted by a signal. They should return 0 on success and -1 on error, just like semop. Each of these should print out a messages to standard error. The messages should begin with 20 blanks. For semwait two messages should be printed, the first being:

and the second: Only one message is printed by semsignal when it is entered.

The child created by the main program should exit after calling perform_command.

The child created by perform_command (the grandchild) should exit if an error occurs. Otherwise this child does an exec and does not return. The perform_command parent should always return.

Make sure that all appropriate calls are restarted if a signal comes in. This includes the semaphore functions. Make sure that all calls do error checking and print an error message if appropriate. The exit function should only be called from main and from the grandchild created by perform_command.

Call the test program described in the next to last paragraph on page 327, testsim.

Create a file called run.input which contains the following lines:
testsim 7 8
testsim 4 3
testsim 5 3
testsim 3 5
Make sure that the file does not contain any blank lines.

Put up a performance meter which shows cpu activity.

Test the program as follows and hand in the output generated.
runsim 2 < run.input

Answer the following question on the second sheet of what you hand in, right after the cover sheet. Make sure the cover sheet has your name on it.

1) Does your program work correctly, as far as you can tell?
2) Describe any error messages produced by your program and explain why they occur.
3) Describe what the performance meter shows when you program is running. Explain why this is the case.
4) What is the purpose of checking to see if any children have finished? (middle of page 327).
5) You are asked to check for finished children twice, once in the main loop using WNOHANG and once before exiting the program. Why is this?

Part II:

Copy runsim.c to runsim1.c and modify it so that it catches the SIGUSR1 signal. Have the signal handler print out to standard error the process ID of the process and the number of currently available licenses. You can obtain this from the current value of the semaphore. You may assume that fprintf is async-signal-safe.

To test this, create the following script called sendsigs:
#!/bin/csh
sleep 1
kill -USR1 $1
sleep 15
kill -USR1 $1
sleep 15
kill -USR1 $1
sleep 12
kill -USR1 $1
sleep 15
kill -USR1 $1

Start your program as before and as soon as possible (within 10 seconds) from another window execute:
sendsigs xxxx
where xxxx is the PID of the runsim process. Describe in detail what happens and explain why the is what you expected. Hand in the output generated.

Part III:

Do the part of the exercise described in the last paragraph on page 327. Call the modified program runsim2 which should be a modified version of runsim1. The access to the semaphore should be robust. Explain how you handled this.

Write a detailed plan of how you tested this part of the program and describe the results.