70 WaitQueue::StackDiscardCleanup onStackDiscard,
71 void* stackDiscardContext) {
73 Time::Timestamp startTime = Time::getTicks();
75 if (!mutex.isOwnedByCurrentThread()) {
76 WARNING(
"ConditionVariable::wait called without owning its mutex");
77 error = MutexNotLocked;
87 me->clearInterruption();
89 auto guard = m_Waiters.acquire();
91 ConditionStackDiscard discard = {
nullptr, onStackDiscard, stackDiscardContext};
92 if (timeout != Time::Infinity) {
93 discard.alarmHandle = Time::addAlarm(timeout);
96 (discard.alarmHandle || onStackDiscard) ? &discardConditionWait :
nullptr, &discard);
98 uintptr_t ra =
reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
99 WaitQueue::WakeReason wakeReason =
104 const Thread::InterruptionReason interruption = me->getInterruptionReason();
108 if (discard.alarmHandle) {
109 void* alarmHandle = discard.alarmHandle;
110 discard.alarmHandle =
nullptr;
111 Time::removeAlarm(alarmHandle);
114 me->clearInterruption();
116 if (interruption == Thread::InterruptedByTimeout) {
118 }
else if (interruption == Thread::InterruptedBySignal) {
120 }
else if (wakeReason == WaitQueue::WakeReason::Unwinding ||
121 wakeReason == WaitQueue::WakeReason::Terminating) {
124 error = TerminationDeferred;
127 Time::Timestamp endTime = Time::getTicks();
132 if (timeout != Time::Infinity) {
133 Time::Timestamp timeConsumed = endTime - startTime;
134 if (timeConsumed >= timeout) {
137 timeout -= timeConsumed;
141 return error == NoError;
MUST_USE_RESULT bool wait(Mutex &mutex, Time::Timestamp &timeout, Error &error, WaitQueue::StackDiscardCleanup onStackDiscard=nullptr, void *stackDiscardContext=nullptr)