This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [BZ 5240][PATCH] Pthread hang where there are still waiters when mutex is in "unlocked" state.
On Sat, 2007-11-24 at 14:04 +0100, Martin Schwidefsky wrote:
> On Fri, 2007-11-23 at 20:43 -0800, Ulrich Drepper wrote:
> > Try the current cvs code.
>
> I did:
>
> > This is true for the old implementation of __lll_timedlock_wait and
> > the current one.
>
> After a thread got back control after lll_futex_timed_wait in
> __lll_timedlock_wait there are three possible lock values:
>
> 0: the lock is free, compare-and-exchange of 2 vs 0 will succeed. The
> unlock following the __lll_timedlock_wait will do the futex_wake.
> 1: the lock is not free, __lll_timedlock_wait will return with
> ETIMEDOUT. The current lock holder will NOT do a futex_wake. The
> current thread is the only one with the knowledge that there might
> be other threads still waiting on a futex call.
> 2: the current lock holder will do a futex_wake when the lock is
> released.
>
> I do not see that case 1) is handled in the old and in the current code.
Addendum: I tried to make the testcase fail on i386 but I found that I
couldn't. After way too long I now know why: the algorithms differ. From
the i486 lowlevellock.S code:
cfi_adjust_cfa_offset(24)
cfi_offset(%edi, -8)
cfi_offset(%esi, -12)
cfi_offset(%ebx, -16)
cfi_offset(%ebp, -20)
/* Check whether the time expired. */
7: cmpl $-ETIMEDOUT, %ecx
je 5f
/* Make sure the current holder knows we are going to sleep. */
movl %edx, %eax
xchgl %eax, (%ebx)
testl %eax, %eax
jz 6b
jmp 1b
Label 7 is reached after futex_wait returned and the cmpxchgl at label 8
failed to take the lock (because the lock value is 1). The return value
of futex_wait is 0 and not -ETIMEDOUT since the wake_up was done before
the timeout expired. In this case the i386 code uses an xchgl to change
the lock value back to 2. The return value of futex_wait carries the
information that this thread has been woken and by upgrading the lock
value to 2 the knowledge that there might be other threads requiring a
wakeup is preserved. This code does not exist in the C implementation.
So there is a solution to this without a futex_wake call on the timeout
path. The analog C code using atomic_exchange_acq has to be added.
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.