This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug nptl/21083] robust timed lock may leave other waiters no chance to wake up
- From: "ma.jiang at zte dot com.cn" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Mon, 06 Nov 2017 11:17:36 +0000
- Subject: [Bug nptl/21083] robust timed lock may leave other waiters no chance to wake up
- Auto-submitted: auto-generated
- References: <bug-21083-131@http.sourceware.org/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=21083
--- Comment #5 from ma.jiang at zte dot com.cn ---
(In reply to Torvald Riegel from comment #4)
> (In reply to ma.jiang from comment #2)
> > (In reply to Carlos O'Donell from comment #1)
> >
> > > When you say "latest glibc sources" do you mean that you tested on master?
> > > How recently?
> > The patch is for glibc-2.24. I checked the trunk code just now, the bug
> > still exist. I have not write a testcase to reproduce the bug, it's quite
> > hard(Although the bug logic is clear)...
>
> I believe this is fixed in master(/trunk). Please have a look at what we do
> with assume_other_futex_waiters: If we ever potentially share FUTEX_WAITERS
> with another thread (C in your example), then after the futex operation we
> make sure to set this flag in any case. This happens either when acquiring
> the mutex (in which case we'll notice this during unlock and wake up C), or
> when not being able to acquire it, in which case there must be another owner
> that interfered and we delegate wake-up responsibilities to that other owner
> by setting FUTEX_WAITERS.
Yes, assume_other_futex_waiters can have FUTEX_WAITERS(after B get waked up),
But the there are still no FUTEX_WAITERS in mutex->__data.__lock. The core
logic is that pthread_mutex_timedlock could return ETIMEDOUT just before adding
FUTEX_WAITERS to mutex->__data.__lock. See attached code chunk.
#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
|| !defined lll_futex_timed_wait_bitset)
struct timeval tv;
struct timespec rt;
/* Get the current time. */
(void) __gettimeofday (&tv, NULL);
/* Compute relative timeout. */
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
{
rt.tv_nsec += 1000000000;
--rt.tv_sec;
}
/* Already timed out? */
if (rt.tv_sec < 0)
return ETIMEDOUT; //->>> We have returned here, with FUTEX_WAITERS
in mutex->__data.__lock.
#endif
/* We cannot acquire the mutex nor has its owner died. Thus, try
to block using futexes. Set FUTEX_WAITERS if necessary so that
other threads are aware that there are potentially threads
blocked on the futex. Restart if oldval changed in the
meantime. */
if ((oldval & FUTEX_WAITERS) == 0)
{
if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
oldval | FUTEX_WAITERS,
oldval)
!= 0)
{
oldval = mutex->__data.__lock;
continue;
}
oldval |= FUTEX_WAITERS;
}
--
You are receiving this mail because:
You are on the CC list for the bug.