Concepts of Programming Languages

(Sean Pound) #1
13.3 Semaphores 589

FETCH(VALUE);
release(emptyspots); { increase empty spaces }
-- consume VALUE --
end loop
end consumer;

The semaphore fullspots causes the consumer task to be queued to wait
for a buffer entry if it is currently empty. The semaphore emptyspots causes
the producer task to be queued to wait for an empty space in the buffer if it
is currently full.

13.3.3 Competition Synchronization


Our buffer example does not provide competition synchronization. Access to
the structure can be controlled with an additional semaphore. This semaphore
need not count anything but can simply indicate with its counter whether the
buffer is currently being used. The wait statement allows the access only if the
semaphore’s counter has the value 1 , which indicates that the shared buffer is not
currently being accessed. If the semaphore’s counter has a value of 0 , there is a
current access taking place, and the task is placed in the queue of the semaphore.
Notice that the semaphore’s counter must be initialized to 1. The queues of
semaphores must always be initialized to empty before use of the queue can begin.
A semaphore that requires only a binary-valued counter, like the one used
to provide competition synchronization in the following example, is called a
binary semaphore.
The example pseudocode that follows illustrates the use of semaphores to
provide both competition and cooperation synchronization for a concurrently
accessed shared buffer. The access semaphore is used to ensure mutually
exclusive access to the buffer. Remember that there may be more than one
producer and more than one consumer.

semaphore access, fullspots, emptyspots;
access.count = 1;
fullspots.count = 0;
emptyspots.count = BUFLEN;

task producer;
loop
-- produce VALUE --
wait(emptyspots); { wait for a space }
wait(access); { wait for access }
DEPOSIT(VALUE);
release(access); { relinquish access }
release(fullspots); { increase filled spaces }
end loop;
end producer;
Free download pdf