This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Is this pthread_cond_wait() race possible
- From: Sebastian Andrzej Siewior <bigeasy at linutronix dot de>
- To: Torvald Riegel <triegel at redhat dot com>
- Cc: libc-alpha at sourceware dot org, tglx at linutronix dot de, Peter Zijlstra <peterz at infradead dot org>, Darren Hart <dvhart at infradead dot org>
- Date: Wed, 7 Jun 2017 18:48:39 +0200
- Subject: Is this pthread_cond_wait() race possible
- Authentication-results: sourceware.org; auth=none
Hi Torvald,
I've been staring at the new pthread_cond_* code. Could you please tell
if this race possible (two wait threads looking at the same __g_signals
value while a third thread signals a wake before going to futex_wait()):
T1 T2 T3
__pthread_cond_wait_common()
__condvar_fetch_add_wseq_acquire (cond, 2);
__pthread_mutex_unlock_usercnt();
__pthread_cond_wait_common()
__condvar_fetch_add_wseq_acquire (cond, 2);
__pthread_mutex_unlock_usercnt();
__pthread_cond_signal()
if ((cond->__data.__g_size[g1] != 0) …
/* Add a signal. */
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
signals = atomic_load_acquire (cond->__data.__g_signals + g);
signals = atomic_load_acquire (cond->__data.__g_signals + g);
signals = 2 signals = 2
/* If there is an available signal, don't block. */
if (signals != 0) if (signals != 0)
break; break;
while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
&signals, signals - 2));
signals = 0
while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
&signals, signals - 2));
signals = (int) -2
… … …
Or is there maybe a synchronisation I missed?
Sebastian