Because of the absence of the sparc32-linux specific version of this file, `nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c' is fetched when building `libc-lowlevellock.o{,s}'. The latter contains just
. . .
#include "lowlevellock.c"
which leads to `nptl/sysdeps/unix/sysv/linux/lowlevellock.c' being actually compiled instead of `nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c'.
As a consequence a futex can be accessed in a non-atomic way when using libc's internal locks, e.g. when performing output to the same stream from different threads.
For example, when the following test is run on a V8 host, this typically leads to a deadlock when all threads are waiting for a futex to become free and there is no one to release it. This happens particularly soon when it's executed this way at a multi-CPU host:
Hi.
Because of the absence of the sparc32-linux specific version of this file, `nptl/sysdeps/ unix/sysv/ linux/libc- lowlevellock. c' is fetched when building `libc-lowlevell ock.o{, s}'. The latter contains just
. . .
#include "lowlevellock.c"
which leads to `nptl/sysdeps/ unix/sysv/ linux/lowlevell ock.c' being actually compiled instead of `nptl/sysdeps/ unix/sysv/ linux/sparc/ sparc32/ lowlevellock. c'.
As a consequence a futex can be accessed in a non-atomic way when using libc's internal locks, e.g. when performing output to the same stream from different threads.
For example, when the following test is run on a V8 host, this typically leads to a deadlock when all threads are waiting for a futex to become free and there is no one to release it. This happens particularly soon when it's executed this way at a multi-CPU host:
$ ./test.sparc32 5 > /dev/null
$ cat test.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *
handler (void *arg)
{
for (;;)
printf ("Thread #%ld\n", (long) arg);
return NULL;
}
int
main (int argc, char **argv)
{
size_t i;
size_t nthreads = (size_t) atoi (argv[1]);
pthread_t *threads = (pthread_t *) malloc (nthreads * sizeof (pthread_t));
for (i = 0; i < nthreads; i++)
pthread_create (&threads[i], NULL, handler, (void *) i);
for (i = 0; i < nthreads; i++)
pthread_join (threads[i], NULL);
free (threads);
return 0;
}