COP4610: Operating Systems & Concurrent Programming up ↑

Programming Assignment #4
Supplemental Advice

Spring 2015

Introduction

This is intended for people who are struggling with this project, and feel they need more guidance. Please keep in mind that there are many good designs for this problem, and I can only cover one here. I apologize to students who have already worked out designs of their own. I would have preferred for everyone to have worked out an individual design, since by doing so you will learn far more than can be learned by just implementing a design that I provided. If you have a viable approach of your own, you will have to decide whether to throw it out and follow this one, or proceed with your own. In the latter case, you may still benefit from reading this if it helps you to conceptualize your own design as a monitor.

This design assumes a non-incremental approach, implementing a pool of re-usable threads, and uses counter to keep track of how many threads are currently available (i.e., ready to serve new connections).

You can view this as a logical monitor. Monitors are described in Section 5.8 of your textbook. You should have read that by now, for the concept, but don't try to apply specifics from the examples there, since the author is trying to describe several variations on the concept, none of which exactly fits your situation here. Note that Pthreads primitives were designed specifically with the monitor model in mind. A mutex is intended to provide the mutual exclusion needed between the operations of a monitor, and condition variables are intended to provide what is needed to implement monitor conditions.

I have written several web-pages of notes showing how to use the Pthread primitives to implement a monitor, including examples of producer-consumer and the classic Barbershop problem. None of them exactly fits this assignment, but you should be able to see from those examples how one maps a conceptual monitor to an implementation using Pthreads.

So, what I provide below is the missing piece: a design of a solution to your exercise P4 as a conceptual montitor. Look at Figure 5.17 in the text, which showns a schematic view of a monitor, having two conditions. Your problem maps to that diagram as follows:

Shared Data

For protected data, you need a count of how many threads are currently waiting to serve connections.

You have the following two logical conditions, whose queues will be provided implicitly by the OS if you map these to Pthread CV's:

The OS also provides the "entry queue", in the form of the queue associated with the Pthread mutex you use to provide mutual exclusion for the monitor.

Initialization Code

You will need initialization code, executed by your program's main/initial thread, to create the server threads and initialize the count to the number of threads created, at the time of main program start-up.

Operations

The monitor needs two logical operations:

Note that each of the operations above requires locking the mutex before the operation begins, waiting on a CV until the associated logical conditions is true (looping as necessary to handle spurious wakeups), and eventually unlock the mutex before returning. Remember that the Pthread cond_wait operation will temporarily unlock the mutex while the thread is blocked on the CV queue.

I recommend you get everything else working before you worry about the complexities of clean shut-down. A simple ctr-C (SIGINT) should kill the entire server if you disable/remove the code that I have provided to install a handler for it. Later, you can re-enable that code and use the global variable shutting_down to implement a cleaner shut-down, if you have time.

T. P. Baker.