| 1 | #include <asm.h> |
|---|---|
| 2 | #include <test/sync.h> |
| 3 | #include <thread/thread_types.h> |
| 4 | #include <time/time.h> |
| 5 | |
| 6 | #ifdef TEST_ENABLED |
| 7 | |
| 8 | bool test_phase_wait(struct test_phase *p, uint32_t expected, |
| 9 | time_ms_t timeout_ms) TSA_NO_ANALYSIS { |
| 10 | time_ms_t deadline = time_get_ms() + timeout_ms; |
| 11 | enum irql irql = spin_lock(&p->lock); |
| 12 | |
| 13 | while (atomic_load_acq(&p->phase) != expected) { |
| 14 | if (atomic_load_acq(&p->poisoned)) { |
| 15 | spin_unlock(&p->lock, irql); |
| 16 | return false; |
| 17 | } |
| 18 | |
| 19 | time_ms_t now = time_get_ms(); |
| 20 | if (now >= deadline) { |
| 21 | spin_unlock(&p->lock, irql); |
| 22 | return false; |
| 23 | } |
| 24 | |
| 25 | condvar_wait_timeout(cv: &p->cv, lock: &p->lock, timeout_ms: deadline - now, irql, out: &irql); |
| 26 | } |
| 27 | |
| 28 | bool poisoned = atomic_load_acq(&p->poisoned); |
| 29 | spin_unlock(&p->lock, irql); |
| 30 | return !poisoned; |
| 31 | } |
| 32 | |
| 33 | #endif /* TEST_ENABLED */ |
| 34 |