| 396 | } |
| 397 | |
| 398 | extern "C" int fastlock_trylock(struct fastlock *lock, int fWeak) |
| 399 | { |
| 400 | int tid; |
| 401 | __atomic_load(&lock->m_pidOwner, &tid, __ATOMIC_ACQUIRE); |
| 402 | if (tid == gettid()) |
| 403 | { |
| 404 | ++lock->m_depth; |
| 405 | return true; |
| 406 | } |
| 407 | |
| 408 | // cheap test |
| 409 | struct ticket ticketT; |
| 410 | __atomic_load(&lock->m_ticket.u, &ticketT.u, __ATOMIC_ACQUIRE); |
| 411 | if (ticketT.m_active != ticketT.m_avail) |
| 412 | return false; |
| 413 | |
| 414 | uint16_t active = ticketT.m_active; |
| 415 | uint16_t next = active + 1; |
| 416 | |
| 417 | struct ticket ticket_expect { { { active, active } } }; |
| 418 | struct ticket ticket_setiflocked { { { active, next } } }; |
| 419 | if (__atomic_compare_exchange(&lock->m_ticket.u, &ticket_expect.u, &ticket_setiflocked.u, fWeak /*weak*/, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) |
| 420 | { |
| 421 | lock->m_depth = 1; |
| 422 | tid = gettid(); |
| 423 | __atomic_store(&lock->m_pidOwner, &tid, __ATOMIC_RELEASE); |
| 424 | ANNOTATE_RWLOCK_ACQUIRED(lock, true); |
| 425 | return true; |
| 426 | } |
| 427 | return false; |
| 428 | } |
| 429 | |
| 430 | extern "C" void fastlock_unlock(struct fastlock *lock) |
| 431 | { |