Fall 97: CIS 307: Homework 4


Given October 28, 1997, due November 17, 1997 by 10pm.

This homework is a continuation of Homeworks 2 and 3. It will have a similar behavior, but changed implementation. Now we will not have the STORE_MANAGER and the HMW_MAIN processes. Each RAND_PROC process will be a main program, each will run on a separate window in your workstation (the same workstation or on different workstations sharing the same file server, like you do with snowhite). You may run as many RAND_PROC processes as you want, but at least two. The RAND_PROC processes are "clients" that do themselves the work of the "server".

The RAND_PROC processes now share a segment of their virtual memories. This shared segment will contain all the data structures previously managed by the STORE_MANAGER process plus an integer field called COUNT. This use of shared memory brings to the problem

Some complications are due to the fact that the process STORE_MANAGER does not exist anymore. Thus the requests from the RAND_PROC processes are not serialized by the STORE_MANAGER and you have to use appropriate locks within the code executed by the RAND_PROC processes. Since there are no pipes or fifos, all the commands (STORE_READ and STORE_UPDATE) will be carried out within the RAND_PROC processes, as function calls with the appropriate parameters, and will return the appropriate values when the operation is completed.
As side effect of each call, a record will be appended to the shared log file log.dat with the following information:

To create critical regions when accessing the shared memory segment, use file locking. Use a separate lock for each entry of the store plus a lock for COUNT (use a single file, say, filelocks.dat, with the different locks represented by different records in the file). See the example on Read and Write locks to see how to protect read and write operations.

Other complications arise since we are using shared memory.
To share memory among processes use the shmget, shmat, shmdt, shmctl operations. shmget creates a segment. It should be invoked with as key IPC_PRIVATE. It should be created by the first RAND_PROC process, deleted by the last one. The process that creates the shared segment should save the id of the segment to a file, segid.dat. The number of running processes will be stored in COUNT.
The RAND_PROC processes check on the existence of the segid.dat file. [For simplicity we assume that all the RAND_PROC processes are yours and they are run from a single directory which is yours.]
If segid.dat is not there, they should

  1. create and initialize [by reading its content from the init.dat file] the segment,
  2. set COUNT to 1,
  3. create the segid.dat file and write the segment id to it (close the file).
If segid.dat already exists, they just read the segment id from the segid.dat file.
Once a RAND_PROC process has the id of the segment, the process attaches to it with shmat and increments COUNT. It will then create a thread that, as in homework 2, will execute randomly TABLE_READ and TABLE_UPDATE. As in homework 2 these are slow operations.
In the main thread the RAND_PROC process interacts with the user by displaying to the user a menu with the following entries:
  1. Print the number of Read and Write operations completed by this process
  2. Terminate.

At termination a RAND_PROC process goes through a complex sequence of actions as at initialization: Decrement COUNT. If COUNT becomes 0, then

  1. Delete the segid.dat file
  2. Detach the process from the shared memory segment with the shmdt command.
  3. Delete the shared segment with the shmctl command.
otherwise just detach the process from the shared memory segment with the shmdt command.

To protect the initialization phase [where you check on segid etc] and the termination phase [where you decrement COUNT etc.] you should use the lock on COUNT.

Often people forget or are unable to delete memory segments. Use at the shell level the command ipcs to determine what shared resources are being used in the system and ipcrm to remove them if no longer needed.