| 1822 | return cvar_do_wait((thread_list*)&q, m, timeout, spinlock_lock, spinlock_unlock); |
| 1823 | } |
| 1824 | int semaphore::wait_interruptible(uint64_t count, Timeout timeout) |
| 1825 | { |
| 1826 | if (count == 0) return 0; |
| 1827 | splock.lock(); |
| 1828 | DEFER(splock.unlock()); |
| 1829 | auto& counter = CURRENT->semaphore_count; |
| 1830 | counter = count; |
| 1831 | DEFER(counter = 0); |
| 1832 | while (!try_subtract(count)) { |
| 1833 | int ret = waitq::wait_defer(timeout, spinlock_unlock, &splock); |
| 1834 | splock.lock(); // assuming errno NOT changed |
| 1835 | if (unlikely(ret < 0)) { // got interrupted |
| 1836 | uint64_t cnt; |
| 1837 | if (!m_ooo_resume && (cnt = m_count.load())) { |
| 1838 | auto eno = errno; |
| 1839 | try_resume(cnt); |
| 1840 | errno = eno; |
| 1841 | } |
| 1842 | return ret; |
| 1843 | } |
| 1844 | } |
| 1845 | return 0; |
| 1846 | } |
| 1847 | void semaphore::try_resume(uint64_t cnt) { |
| 1848 | assert(cnt); |
| 1849 | while(true) { |