futex.c
author Hajime Tazaki <tazaki@nict.go.jp>
Wed, 13 Feb 2013 22:37:34 +0900
changeset 651 9d7e2cd9633b
parent 538 35d137b26ca1
permissions -rw-r--r--
add a testcase to reproduce threaded dlclose crash (Bug 1513)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     1
#include "futex.h"
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     2
#include "machine.h"
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     3
#include "system.h"
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
     4
#include "vdl-alloc.h"
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
     5
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
     6
struct Futex *futex_new (void)
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
     7
{
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
     8
  struct Futex *futex = vdl_alloc_new (struct Futex);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
     9
  futex_construct (futex);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    10
  return futex;
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    11
}
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    12
void futex_delete (struct Futex *futex)
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    13
{
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    14
  futex_destruct (futex);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    15
  vdl_alloc_delete (futex);
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    16
}
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    17
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    18
void futex_construct (struct Futex *futex)
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    19
{
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    20
  futex->state = 0;
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    21
}
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    22
void futex_destruct (struct Futex *futex)
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    23
{}
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    24
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    25
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    26
void futex_lock (struct Futex *futex)
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    27
{
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    28
  uint32_t c;
461
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
    29
  if ((c = machine_atomic_compare_and_exchange (&futex->state, 0, 1)) != 0)
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    30
    {
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    31
      do {
461
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
    32
	if (c == 2 || machine_atomic_compare_and_exchange (&futex->state, 1, 2) != 0)
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    33
	  {
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    34
	    system_futex_wait (&futex->state, 2);
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    35
	  }
461
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 231
diff changeset
    36
      } while ((c = machine_atomic_compare_and_exchange (&futex->state, 0, 2)) != 0);
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    37
    }
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    38
}
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    39
538
35d137b26ca1 cleanup vdl.h API
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents: 461
diff changeset
    40
void futex_unlock (struct Futex *futex)
231
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    41
{
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    42
  if (machine_atomic_dec (&futex->state) != 1) 
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    43
    {
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    44
      futex->state = 0;
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    45
      system_futex_wake (&futex->state, 1);
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    46
    }
41ad566b03d8 lock dlopen/dlclose
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff changeset
    47
}