CMSC 412

Alternative to Book Implemenatation of P()

The book (Silberschatz and Galvin) suggests the following definition for P().
    sem--;
    if ( sem < 0 ) then
       begin
         add process to semaphore queue
         block
       end
Of course, because it is in a book, and because it is so important, it is not an incorrect implementation, but it is a bit limited. In this definition, the value of the semaphore can be negative. If it is negative, then its absolute value determines how many processes are blocked on this semaphore

Because of the way P is defined in the book, V must be implemented in a more restricted manner. You increment the value, as usual. However, when the value is negative, at most one process can be woken up (placed on the ready queue) given a V operation. When the unblocked process runs, it will be practically out of the P operation since it has completed the if statement.

As mentioned earlier, the drawback is that at most one process can be placed on the ready queue on a V operation. You can also implement V to place all process blocked on this semaphore on the ready queue (the value is still only incremented by 1). Basically, the first process that runs will be the one that actually wakes up. The rest will check eventually reblock. If you choose to wake all processes up (which you will NOT do in this project) and you want to allow negative values for semaphroes, then you need to extend the implementation given in the book. Specifically, you will need to use additional variables to keep track of how many processes should be awaken, and the P implementation needs to be reworked. All in all, this would be a pain.

There is yet another way to implement semaphores which is somewhat closer in spirit to the definition of a semaphore, and allows for more than one process to be placed on the ready queue in a V operation while not violating the semantics of V. Consider this implementation.

P(sem):    while ( sem <= 0 ) then  // sem should never be < 0
            begin
              add process to semaphore queue
              block
            end
           sem--;  // decrement occurs after while loop

V(sem):   sem++;
          Wake one or more processes from semaphore queue
Note the difference between the two implementations. This implementation does not allow the value of the semaphore to go negative. It also has a while statement instead of an if statement. Hence, a process that is placed on the ready queue, and then runs, will check the condition in the while loop, and if the value of the semaphore is positive, it will decrement the value of the semaphore.

Note V remains roughly the same, except that you are now allowed to wake one or more processes (if there are any) up. In the book implementation, you must only wake one process up.

By studying the two implementations, you can get a better understanding of how semaphores are implemented. You can use either one since this project only wakes one process up. Were you to wake more than one process, then you would have to use the second implementation (or go through the much more difficult process of adding additional auxiliary variables) to deal with the negative values of the semaphore. Think about it. It's a good exercise.