mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-16 10:52:22 -07:00
3afa2736b7
When locking, we were not loading m.serving atomically and so the optimizer could have hoisted the check out of the loop, thus resulting in an infinite loop.
28 lines
554 B
Odin
28 lines
554 B
Odin
package sync
|
|
|
|
foreign {
|
|
@(link_name="llvm.x86.sse2.pause")
|
|
yield_processor :: proc() ---
|
|
}
|
|
|
|
Ticket_Mutex :: struct {
|
|
ticket: u64,
|
|
serving: u64,
|
|
}
|
|
|
|
ticket_mutex_init :: proc(m: ^Ticket_Mutex) {
|
|
atomic_store(&m.ticket, 0, .Relaxed);
|
|
atomic_store(&m.serving, 0, .Relaxed);
|
|
}
|
|
|
|
ticket_mutex_lock :: inline proc(m: ^Ticket_Mutex) {
|
|
ticket := atomic_add(&m.ticket, 1, .Relaxed);
|
|
for ticket != atomic_load(&m.serving, .Acquire) {
|
|
yield_processor();
|
|
}
|
|
}
|
|
|
|
ticket_mutex_unlock :: inline proc(m: ^Ticket_Mutex) {
|
|
atomic_add(&m.serving, 1, .Relaxed);
|
|
}
|