This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]