#include "unify.h"
Event counters and sequencers are abstract data types that provide
scalable, efficient synchronization for distributed programs. Event
counters allow
Create_Event(3),
Destroy_Event(3),
Advance(3),
Await(3),
Await_with_Timeout(3), and
Read_Count(3) operations.
Conceptually, the data part of an event counter is just an integer
count. When an event counter is created, count
is initialized to 0. Advance(3)
increments count.
Await(3) takes an
integer as a parameter and blocks until count becomes
greater than or equal to the integer it is passed.
Await_with_Timeout(3)
takes an integer and a timeval structure containing a timeout as parameters
and blocks until count becomes greater than or equal to the
integer it is passed or timeout is expired. Returns the count
when unblocking occured.
Read_Count(3) returns a
number that is not greater than count.
Event counters alone are not general enough to implement all
interesting forms of synchronization. Sequencers are needed to
provide serialization. That is they can be used to order operations.
Create_Sequencer(3),
Destroy_Sequencer(3),
and Get_Ticket(3) are used
to operate on sequencers. Each sequencer has a count
variable which is initialized to zero. When a process calls Get_Ticket(3), the sequencer
atomically increments count and returns the new
count to the calling process.
The following code shows how to implement a simple semaphore using event counters and sequencers without error checking. Application programs should check return codes to verify correct operation.
typdef struct semtype_t
{
int event_id;
int seq_id;
} SemType;
void SemaphoreInit(SemType *sem, unsigned int count)
{
sem->event = Create_Event();
sem->seq = Create_Sequencer();
while(count >= 0) {
Advance(sem->event);
count--;
}
}
void SemaphoreDestroy(SemType *sem)
{
DestroyEvent(sem->event);
DestorySequencer(sem->seq);
}
void SemaphoreSignal(SemType *sem)
{
Advance(sem->event);
}
void SemaphoreWait(SemType *sem)
{
Await(GetTicket(sem->seq));
}
Advance(3), Await(3), Await_with_Timeout(3), Create_Event(3), Destroy_Event(3), Read_Count(3), Create_Sequencer(3), Destroy_Sequencer(3), Get_Ticket(3), unifyintro(3)