| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package sync
- import "core:intrinsics"
- cpu_relax :: #force_inline proc "contextless" () {
- intrinsics.cpu_relax();
- }
- Condition_Mutex_Ptr :: union{^Mutex, ^Blocking_Mutex};
- 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 :: #force_inline proc(m: ^Ticket_Mutex) {
- ticket := atomic_add(&m.ticket, 1, .Relaxed);
- for ticket != atomic_load(&m.serving, .Acquire) {
- intrinsics.cpu_relax();
- }
- }
- ticket_mutex_unlock :: #force_inline proc(m: ^Ticket_Mutex) {
- atomic_add(&m.serving, 1, .Relaxed);
- }
- Benaphore :: struct {
- counter: int,
- sema: Semaphore,
- }
- benaphore_init :: proc(b: ^Benaphore) {
- intrinsics.atomic_store(&b.counter, 0);
- semaphore_init(&b.sema);
- }
- benaphore_destroy :: proc(b: ^Benaphore) {
- semaphore_destroy(&b.sema);
- }
- benaphore_lock :: proc(b: ^Benaphore) {
- if intrinsics.atomic_add_acq(&b.counter, 1) > 1 {
- semaphore_wait_for(&b.sema);
- }
- }
- benaphore_try_lock :: proc(b: ^Benaphore) -> bool {
- v, _ := intrinsics.atomic_cxchg_acq(&b.counter, 1, 0);
- return v == 0;
- }
- benaphore_unlock :: proc(b: ^Benaphore) {
- if intrinsics.atomic_sub_rel(&b.counter, 1) > 0 {
- semaphore_post(&b.sema);
- }
- }
- Recursive_Benaphore :: struct {
- counter: int,
- owner: int,
- recursion: int,
- sema: Semaphore,
- }
- recursive_benaphore_init :: proc(b: ^Recursive_Benaphore) {
- intrinsics.atomic_store(&b.counter, 0);
- semaphore_init(&b.sema);
- }
- recursive_benaphore_destroy :: proc(b: ^Recursive_Benaphore) {
- semaphore_destroy(&b.sema);
- }
- recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) {
- tid := current_thread_id();
- if intrinsics.atomic_add_acq(&b.counter, 1) > 1 {
- if tid != b.owner {
- semaphore_wait_for(&b.sema);
- }
- }
- // inside the lock
- b.owner = tid;
- b.recursion += 1;
- }
- recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool {
- tid := current_thread_id();
- if b.owner == tid {
- intrinsics.atomic_add_acq(&b.counter, 1);
- } else {
- v, _ := intrinsics.atomic_cxchg_acq(&b.counter, 1, 0);
- if v != 0 {
- return false;
- }
- // inside the lock
- b.owner = tid;
- }
- b.recursion += 1;
- return true;
- }
- recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) {
- tid := current_thread_id();
- assert(tid == b.owner);
- b.recursion -= 1;
- recursion := b.recursion;
- if recursion == 0 {
- b.owner = 0;
- }
- if intrinsics.atomic_sub_rel(&b.counter, 1) > 0 {
- if recursion == 0 {
- semaphore_post(&b.sema);
- }
- }
- // outside the lock
- }
|