futex.c
author Mathieu Lacage <mathieu.lacage@alcmeon.com>
Sat, 23 Feb 2013 20:59:51 +0100
changeset 656 e4817d48962f
parent 538 35d137b26ca1
permissions -rw-r--r--
basic test for tls

#include "futex.h"
#include "machine.h"
#include "system.h"
#include "vdl-alloc.h"

struct Futex *futex_new (void)
{
  struct Futex *futex = vdl_alloc_new (struct Futex);
  futex_construct (futex);
  return futex;
}
void futex_delete (struct Futex *futex)
{
  futex_destruct (futex);
  vdl_alloc_delete (futex);
}

void futex_construct (struct Futex *futex)
{
  futex->state = 0;
}
void futex_destruct (struct Futex *futex)
{}


void futex_lock (struct Futex *futex)
{
  uint32_t c;
  if ((c = machine_atomic_compare_and_exchange (&futex->state, 0, 1)) != 0)
    {
      do {
	if (c == 2 || machine_atomic_compare_and_exchange (&futex->state, 1, 2) != 0)
	  {
	    system_futex_wait (&futex->state, 2);
	  }
      } while ((c = machine_atomic_compare_and_exchange (&futex->state, 0, 2)) != 0);
    }
}

void futex_unlock (struct Futex *futex)
{
  if (machine_atomic_dec (&futex->state) != 1) 
    {
      futex->state = 0;
      system_futex_wake (&futex->state, 1);
    }
}