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; }
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; } }
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; }