Skip to content

Commit

Permalink
Fix pthread_cond_wait race on macOS (#82893)
Browse files Browse the repository at this point in the history
The native runtime event implementations for nativeaot and GC use
pthread_cond_wait to wait for the event and pthread_cond_broadcast
to signal that the event was set. While the usage of the
pthread_cond_broadcast conforms with the documentation, it turns out
that glibc before 2.25 had a race in the implementation that can
cause the pthread_cond_broadcast to be unnoticed and the wait
waiting forever. It turns out that macOS implementation has the
same issue.
The fix for the issue is to call pthread_cond_broadcast while the
related mutex is taken.

This change fixes intermittent crossgen2 hangs with nativeaot build of
crossgen2 reported in #81570. I was able to repro the hang locally in
tens of thousands of iterations of running crossgen2 without any arguments
(the hang occurs when server GC creates threads). With this fix,
it ran without problems over the weekend, passing 5.5 million iterations.

Co-authored-by: Jan Vorlicek <janvorli@microsoft.com>
  • Loading branch information
github-actions[bot] and janvorli authored Mar 8, 2023
1 parent dbb333c commit 43b0192
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 4 deletions.
3 changes: 1 addition & 2 deletions src/coreclr/gc/unix/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,9 @@ class GCEvent::Impl
{
pthread_mutex_lock(&m_mutex);
m_state = true;
pthread_mutex_unlock(&m_mutex);

// Unblock all threads waiting for the condition variable
pthread_cond_broadcast(&m_condition);
pthread_mutex_unlock(&m_mutex);
}

void Reset()
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,9 @@ class UnixEvent
{
pthread_mutex_lock(&m_mutex);
m_state = true;
pthread_mutex_unlock(&m_mutex);

// Unblock all threads waiting for the condition variable
pthread_cond_broadcast(&m_condition);
pthread_mutex_unlock(&m_mutex);
}

void Reset()
Expand Down

0 comments on commit 43b0192

Please sign in to comment.