type semaphore = record count : integer; 1. q : queue of processes; end record; procedure initsem (s : in out semaphore; n : integer) is begin s.count := n; initialize s.q to the empty queue; end; procedure P(s : in out semaphore) is begin 2. s.count := s.count - 1; 3. if s.count < 0 then 4. Remove this process from Running, add it to s.q, and reschedule; end; procedure V(s : in out semaphore) is begin 5. s.count := s.count + 1; 6. if s.count <= 0 and s.q is not empty then 7. Remove a process from s.q, add it to the Ready Queue, and reschedule; end;
Using semaphores we can achieve a number of different behaviors:
Nutt's Implementation
Here we show code similar to the code
used by G.J.Nutt in his Operating Systems book.
This code implements N semaphores for a multiprocesing system.
#define N .. /* The number of semaphores */ int value[N]; /* Keeps the count for the semaphores */ boolean sem[N]; /* Spinlocks to protect critical region */ /* of semaphore */ boolean hold[N]; /* Used to temporarily "enqueue" tasks */ /* waiting on sem */ void initsem(int s, m) { value[s] = m; sem[s] = FALSE; hold[s] = TRUE;} void P(int s) { while (TS(sem[s])); /* Lock */ value[s]--; if (value[s] < 0) { sem[s] = FALSE; /* Unlock */ while(TS(hold[s])) yield(Q); /* Here the process enters */ /* a new Critical Region where it gives */ /* control to Q, a scheduler. It is a loop */ /* since we may repeatedly be given control*/ /* back from yield and find a blocked semaphore.*/ }else sem[s] = FALSE;} /* Unlock */ void V(int s){ while (TS(sem[s])); /* Lock */ value[s]++; if (value[s] <= 0){ /* Somebody is waiting in hold to enter CR*/ while (!hold[s]); /* We check if there is a concurrent V. */ /* It is a loop */ /* because we might have two or more */ /* concurrent V operations executing.*/ hold[s] = FALSE; /* Here we free a process waiting in P.*/ } sem[s] = FALSE;} /* Unlock */
Implementation of Semaphores in XINU
You may examine the implementation of semaphores in
XINU. Examine in particular the files sem.h,
wait.c, and signal.c. Do you think that this implementation works only
in a shared memory mutiprocessing system? or only in a single processor
system?
An implementation for testing programs that use semaphores
Here is code that implements semaphores as pipes.
Of course nobody would ever think to use such an implementation in practice.
This code is shown here for two reasons. Firstly, it can be used to test
concurrent programs with semaphores. Second, it reminds us that IPC
primitives can be implemented in terms of each other. That is, IPC primitives
are chosen not just on the basis of functionality, but also on the basis of
performance (things like data rate and latency).
ingargiola.cis.temple.edu