atomic_exchange
Atomically exchanges a value in memory.
Test atomic_exchange in a live shader
Open the playground, start from a visual preset, and wire atomic_exchange into the fragment stage to see how it behaves with real values.
Open PlaygroundLive Demo Pending
The atomic_exchange function atomically replaces the value at a memory location and returns the original value.
Signature
atomic_exchange(dest, value)
Parameters
| Parameter | Description |
|---|---|
dest | Integer lvalue to modify atomically |
value | New value to store |
Return Value
Returns the original value at dest before the exchange.
Example
pipeline SpinLock {
pass "Main" {
compute "Main" [64, 1, 1] {
// Try to acquire lock
int lockIndex = getTileLock(tileId);
int expected = 0;
// Spin until we acquire the lock
while (atomic_exchange(lockBuffer[lockIndex], 1) != 0) {
// Lock was held, try again
}
// Critical section - we have the lock
processExclusive(tileId);
// Release lock
atomic_exchange(lockBuffer[lockIndex], 0);
}
}
}Common Use Cases
Spin Lock
// Acquire lock
while (atomic_exchange(lock, 1) != 0) {
// spin
}
// ... critical section ...
atomic_exchange(lock, 0); // ReleaseSwap Values
// Atomically swap in new value
int oldValue = atomic_exchange(data, newValue);
processOldValue(oldValue);Double Buffering
// Swap buffer index
int oldBuffer = atomic_exchange(activeBuffer, newBuffer);
// oldBuffer is now safe to write toState Machine
// Atomically transition state
int previousState = atomic_exchange(state, newState);
if (previousState != expectedState) {
// Handle unexpected state
}One-Shot Triggers
// First thread to arrive triggers action
int wasTriggered = atomic_exchange(trigger, 1);
if (wasTriggered == 0) {
// This thread triggered - do one-time action
performOneTimeAction();
}Spin Lock Caution
Spin locks in GPU shaders can cause severe performance issues or hangs if not all threads make progress. Prefer lock-free algorithms when possible.
Compare-Exchange Alternative
For conditional updates (only exchange if current value matches expected), use atomic_cmp_exchange instead.
Compiled Output
When compiled to GLSL:
atomicExchange(dest, value)
When compiled to HLSL:
InterlockedExchange(dest, value, originalValue)
When compiled to SPIR-V:
Uses OpAtomicExchange instruction.
See Also
- atomic_cmp_exchange - Conditional exchange
- atomic_add - Atomic add