Alpha semaphores are defined as type sema_t.
The following figure shows its principal elements and how it is
implemented in relation with other kernel structures.
A spinlock is used to protect the data structures that implement
the semaphore.
Table 1-9 Principal
elements of struct sema (sema_t)
Element | Purpose |
---|
*sa_lock | Pointer to spinlock protecting
the semaphore. |
sa_count | Value of semaphore count,
which indicates whether the semaphore is available. |
*sa_owner | Pointer to kernel thread
that owns a lock on the semaphore. |
*sa_wait_list | Pointer to head of kthread
waiting on the semaphore. |
*sa_prev, *sa_next | Previous and next semaphore
in per-kthread list; used to link semaphores owned by a given thread
together. |
sa_order | Deadlock protocol order
for semaphore. |
sa_priority | Priority of a mutual exclusion
semaphore. |
sa_missers | Array of processors used for semaphore arbitration. |
Performance is a key consideration for use of alpha semaphores.
To prevent "starvation" of code, the following
algorithm governs their use:
When a CPU misses on an alpha semaphore, the CPU's
number is put in an array (sa_missers),
indexed according to the priority of that processor for the semaphore.
The processor with the lowest entry in the array is favored. This
arrangement ensures fair access to the semaphore.
A value called asema_max_ignore
limits the number of times a semaphore is checked and found unavailable.
Once this value is exceeded, arbitration code (asema_available())
ensures that the CPU does not get starved for a semaphore.