mirror of git://sourceware.org/git/glibc.git
On s390 (31bit) if glibc is build with -Os, pthread_join sometimes
blocks indefinitely. This is e.g. observable with
testcase intl/tst-gettext6.
pthread_join is calling lll_wait_tid(tid), which performs the futex-wait
syscall in a loop as long as tid != 0 (thread is alive).
On s390 (and build with -Os), tid is loaded from memory before
comparing against zero and then the tid is loaded a second time
in order to pass it to the futex-wait-syscall.
If the thread exits in between, then the futex-wait-syscall is
called with the value zero and it waits until a futex-wake occurs.
As the thread is already exited, there won't be a futex-wake.
In lll_wait_tid, the tid is stored to the local variable __tid,
which is then used as argument for the futex-wait-syscall.
But unfortunately the compiler is allowed to reload the value
from memory.
With this patch, the tid is loaded with atomic_load_acquire.
Then the compiler is not allowed to reload the value for __tid from memory.
ChangeLog:
[BZ #23137]
* sysdeps/nptl/lowlevellock.h (lll_wait_tid):
Use atomic_load_acquire to load __tid.
(cherry picked from commit
|
||
|---|---|---|
| .. | ||
| bits | ||
| sys | ||
| Implies | ||
| Makeconfig | ||
| Makefile | ||
| Subdirs | ||
| aio_misc.h | ||
| allocrtsig.c | ||
| fork.c | ||
| fork.h | ||
| futex-internal.h | ||
| gai_misc.h | ||
| internaltypes.h | ||
| jmp-unwind.c | ||
| libc-lock.h | ||
| libc-lockP.h | ||
| librt-cancellation.c | ||
| lowlevellock-futex.h | ||
| lowlevellock.h | ||
| malloc-machine.h | ||
| nptl-signals.h | ||
| pthread-functions.h | ||
| pthread.h | ||
| setxid.h | ||
| shm-directory.h | ||
| sigfillset.c | ||
| stdio-lock.h | ||
| tcb-offsets.h | ||
| tst-mqueue8x.c | ||
| unwind-forcedunwind.c | ||