Line 220:
Line 220:
== Light Event ==
== Light Event ==
+
+
== Address Arbiters ==
+
+
Address arbiters are a low-level primitive to implement synchronization based on a counter stored at some user-specified virtual memory address. Address arbiters are used to put the current thread to sleep until the counter is signaled. Both of these tasks are implemented in ArbitrateAddress.
+
+
===CreateAddressArbiter===
+
Result CreateAddressArbiter(Handle* arbiter)
+
+
Creates an address arbiter handle for use with ArbitrateAddress.
+
+
=== ArbitrateAddress ===
+
Result ArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds)
+
+
if <code>type</code> is SIGNAL, the ArbitrateAddress call will resume up to <code>value</code> of the threads waiting on <code>addr</code> using an arbiter, starting with the highest-priority threads. If <code>value</code> is negative, all of these threads are released. <code>nanoseconds</code> remains unused in this mode.
+
+
The other modes are used to (conditionally) put the current thread to sleep based on the memory word at virtual address <code>addr</code> until another thread signals that address using ArbitrateAddress with the <code>type</code> SIGNAL. WAIT_IF_LESS_THAN will put the current thread to sleep if that word is smaller than <code>value</code>. DECREMENT_AND_WAIT_IF_LESS_THAN will furthermore decrement the memory value before the comparison. WAIT_IF_LESS_THAN_TIMEOUT and DECREMENT_AND_WAIT_IF_LESS_THAN_TIMEOUT will do the same as their counterparts, but will have thread execution resume if <code>nanoseconds</code> nanoseconds pass without <code>addr</code> being signaled.
+
+
=== enum ArbitrationType ===
+
{| class="wikitable" border="1"
+
! Address arbitration type
+
! Value
+
|-
+
| SIGNAL
+
| 0
+
|-
+
| WAIT_IF_LESS_THAN
+
| 1
+
|-
+
| DECREMENT_AND_WAIT_IF_LESS_THAN
+
| 2
+
|-
+
| WAIT_IF_LESS_THAN_TIMEOUT
+
| 3
+
|-
+
| DECREMENT_AND_WAIT_IF_LESS_THAN_TIMEOUT
+
| 4
+
|}