(* Shared semaphore *)
Semaphore token; (* initial value 1 *)
void ProcessA () void ProcessB ()
{ {
while (1) { while (1) {
... ...
Wait(Token) Wait(Token)
(* critical *) (* critical *)
Signal(Token) Signal(Token)
... ...
} }
} }

void Wait (s)
{
when s>0
s--;
}
void Signal (s)
{
s++;
}
void put (char ch) char get (void)
{ {
Wait(Mutex) Wait(Mutex)
(* safe to alter *) (* safe to alter *)
(* buffer *) (* buffer *)
place ch into buf remove ch from buf
Signal(Mutex) Signal(Mutex)
return ch;
} }
char buffer[Max]; (* global data *)
SEMAPHORE Mutex; (* global data *)
void put (char ch) char get (void)
{ {
Wait(SpaceAvailable) Wait(ItemAvailable)
Wait(Mutex) Wait(Mutex)
(* safe to alter *) (* safe to alter *)
(* buffer *) (* buffer *)
place ch into buf remove ch from buf
Signal(Mutex) Signal(Mutex)
Signal(ItemAvailable) Signal(SpaceAvailable)
return ch;
} }
char buffer[Max]; (* global data *)
SEMAPHORE Mutex; (* global data *)




while (s <= 0) ; s--;
s++
void Wait (SEMAPHORE s)
{
save and disable processor interrupts ;
if value of s > 0
then
dec(value of s)
else
remove CurrentProcess from run queue ;
mark CurrentProcess as WaitOnSem ;
add CurrentProcess to semaphore q ;
Reschedule
end
restore processor interrupts
}
void Signal (SEMAPHORE s)
{
save and disable processor interrupts ;
if a process is on s q
then
remove process, p, from s q
alter process, p, status to runnable ;
add p to the run queue ;
Reschedule
else
inc(value of s)
end
restore processor interrupts
}
process A process B
while (1) { while (1) {
Wait(Mutex) ; Wait(Mutex) ;
do something do something
Signal(Mutex); Signal(Mutex) ;
} }
SEMAPHORE
queue
value
RunQueue
0
1


typedef struct Semaphore {
unsigned int Value;
/* semaphore value */
EntityName SemName;
/* semaphore name for debugging */
void *Who;
/* queue of waiting processes */
struct SemQueue {
struct Semaphore *Right,
*Left;
} ExistsQ;
/* list of existing semaphores */
} Semaphore;
Semaphore *Executive_InitSemaphore
(unsigned int v, char *Name,
const int Name_HIGH)
{
Semaphore *s;
OnOrOff ToOldState;
/* disable interrupts */
ToOldState = SYSTEM_TurnInterrupts(Off);
SysStorage_ALLOCATE((void **)&s,
sizeof(Semaphore));
/* initial value of semaphore */
s->Value = v;
/* save the name for future debugging */
StrLib_StrCopy(Name, Name_HIGH,
(char *)&s->SemName,
MaxCharsInName);
/* no one waiting on this semaphore yet */
s->Who = NULL;
/* add semaphore to exists list */
AddToSemaphoreExists(s);
/* restore interrupts */
ToOldState = SYSTEM_TurnInterrupts(ToOldState);
return s;
}
typedef struct Descriptor {
PROCESS Volatiles;
/* process volatile environment */
struct DesQueue {
struct Descriptor *Right, *Left;
} ReadyQ,
/* queue of ready processes */
ExistsQ,
/* queue of existing processes */
SemaphoreQ;
/* queue of waiting processes */
Semaphore *Which;
/* which semaphore are we waiting*/
EntityName RunName;
/* process name for debugging */
State Status;
/* state of process */
Priority RunPriority;
/* runtime priority of process */
unsigned int Size;
/* Maximum stack size */
void *Start;
/* Stack start */
BOOLEAN Debugged;
/* Does user want to debug a */
/* deadlocked process? */
} Descriptor;
ie p->Status = Runnable
AddToSemaphore(&s->Who, p) ; p->Status = WaitOnSem p->Which = s
p = SubFromSemaphoreTop(&s->Who) ; p->Which = NULL ; p->Status = Runnable ; AddToReady(p)
RunQueue[d->RunPriority] = d;
DESCRIPTOR Resume (DESCRIPTOR d)
{
disable interrupts ;
if d is Suspended
then
change Status of d to Runnable ;
add to ready q
make sure d is at top of
ready q
Reschedule
else
Halt(’not suspended’,
__LINE__, __FILE__)
end
restore interrupts ;
return d;
}
void Suspend ;
{
disable interrupts ;
remove process from ready q ;
alter status ;
Reschedule ;
restore interrupts ;
}
This document was produced using groff-1.19.