Comment 1 for bug 1091186

Revision history for this message
In , Ilmalakhov (ilmalakhov) wrote :

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-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:

$ ./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;
}