int
__new_sem_trywait (sem_t *sem)
{
  struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
  int val;

  if (isem->value > 0)
    {
      if (__atomic_is_v9)
	val = atomic_decrement_if_positive (&isem->value);
      else
	{
	  __sparc32_atomic_do_lock24 (&isem->lock);
	  val = isem->value;
	  if (val > 0)
	    isem->value = val - 1;
	  __sparc32_atomic_do_unlock24 (&isem->lock);
	}
      if (val > 0)
	return 0;
    }

  __set_errno (EAGAIN);
  return -1;
}
Ejemplo n.º 2
0
int
__new_sem_post (sem_t *sem)
{
  struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
  int nr;

  if (__atomic_is_v9)
    nr = atomic_increment_val (&isem->value);
  else
    {
      __sparc32_atomic_do_lock24 (&isem->lock);
      nr = ++(isem->value);
      __sparc32_atomic_do_unlock24 (&isem->lock);
    }
  atomic_full_barrier ();
  if (isem->nwaiters > 0)
    {
      int err = lll_futex_wake (&isem->value, 1,
				isem->private ^ FUTEX_PRIVATE_FLAG);
      if (__builtin_expect (err, 0) < 0)
	{
	  __set_errno (-err);
	  return -1;
	}
    }
Ejemplo n.º 3
0
int
__new_sem_wait (sem_t *sem)
{
  /* First check for cancellation.  */
  CANCELLATION_P (THREAD_SELF);

  int *futex = (int *) sem;
  int err;

  do
    {
      int val;
      if (__atomic_is_v9)
	val = atomic_decrement_if_positive (futex);
      else
	{
	  __sparc32_atomic_do_lock24 (futex + 1);
	  val = *futex;
	  if (val > 0)
	    *futex = val - 1;
	  __sparc32_atomic_do_unlock24 (futex + 1);
	}
      if (val > 0)
	return 0;

      /* Enable asynchronous cancellation.  Required by the standard.  */
      int oldtype = __pthread_enable_asynccancel ();

      err = lll_futex_wait (futex, 0);

      /* Disable asynchronous cancellation.  */
      __pthread_disable_asynccancel (oldtype);
    }
  while (err == 0 || err == -EWOULDBLOCK);

  __set_errno (-err);
  return -1;
}