Skip to content

Commit 3d3fa2f

Browse files
committed
Fix commit dfe4e77: check hasWaiters() in Enqueue
* We were checking hasWaiters() in MCCondWait, and if no waiters, we set the mutex to NULL, associated with that condition variable. That corrupted the stack. We now check in MCCondEnqueue that if hasWaiters() is true, then the old mutex associated with the condition variable is the same as the new mutex being associated with it.
1 parent 514a098 commit 3d3fa2f

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
Version 1.2.0 release notes (DATE: TBD)
2+
==========================================
3+
* A long-standing bug affecting condition variables was removed.
4+
* The experimental livelock support was improved using a new heuristic.
5+
16
Version 1.1.0 release notes (Oct. 7, 2025)
27
==========================================
38

src/transitions/cond/MCCondEnqueue.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,19 @@ MCCondEnqueue::dynamicCopyInState(const MCStack *state) const
177177
void
178178
MCCondEnqueue::applyToState(MCStack *state)
179179
{
180+
// POSIX standard says that the dynamic binding of a condition variable
181+
// to a mutex is removed when the last thread waiting on that cond var is
182+
// unblocked (i.e., has re-acquired the associated mutex of the cond var).
183+
if (this->conditionVariable->hasWaiters() &&
184+
this->conditionVariable->mutex != this->mutex) {
185+
mcprintf("\n*** ERROR (pthread_cond_wait/traceId: %d):\n"
186+
"*** pthread_cond_wait() was called with a new mutex,\n"
187+
"*** even though a different thread had called\n"
188+
"*** pthread_cond_wait() on a different mutex and that thread\n"
189+
"*** was still waiting on this same condition variable.\n",
190+
traceId);
191+
mc_stop_model_checking(EXIT_FAILURE);
192+
}
180193
/* Insert this thread into the waiting queue */
181194
this->conditionVariable->addWaiter(this->getThreadId());
182195
this->conditionVariable->mutex = this->mutex;

src/transitions/cond/MCCondWait.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,6 @@ MCCondWait::applyToState(MCStack *state)
7979
const tid_t threadId = this->getThreadId();
8080
this->conditionVariable->mutex->lock(threadId);
8181
this->conditionVariable->removeWaiter(threadId);
82-
// POSIX standard says that the dynamic binding of a condition variable
83-
// to a mutex is removed when the last thread waiting on that cond var is
84-
// unblocked (i.e., has re-acquired the associated mutex of the cond var).
85-
if (! this->conditionVariable->hasWaiters()) {
86-
this->conditionVariable->mutex = nullptr;
87-
}
8882
}
8983

9084
bool

0 commit comments

Comments
 (0)