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.