Unlock the lock at index. We need a lane sync to keep this function convergent, otherwise the compiler will sink the store and deadlock.
| 209 | /// Unlock the lock at index. We need a lane sync to keep this function |
| 210 | /// convergent, otherwise the compiler will sink the store and deadlock. |
| 211 | RPC_ATTRS void unlock(uint64_t lane_mask, uint32_t index) { |
| 212 | // Do not move any writes past the unlock. |
| 213 | __scoped_atomic_thread_fence(__ATOMIC_RELEASE, __MEMORY_SCOPE_DEVICE); |
| 214 | |
| 215 | // Use exactly one thread to clear the nth bit in the lock array Must |
| 216 | // restrict to a single thread to avoid one thread dropping the lock, then |
| 217 | // an unrelated warp claiming the lock, then a second thread in this warp |
| 218 | // dropping the lock again. |
| 219 | clear_nth(lock, index, rpc::is_first_lane(lane_mask)); |
| 220 | rpc::sync_lane(lane_mask); |
| 221 | } |
| 222 | |
| 223 | /// Number of bytes to allocate for an inbox or outbox. |
| 224 | RPC_ATTRS static constexpr uint64_t mailbox_bytes(uint32_t port_count) { |
no test coverage detected