int _sem_wait(sem_t *sem) { struct pthread *curthread; int retval; if (sem_check_validity(sem) != 0) return (-1); curthread = _get_curthread(); if ((*sem)->syssem != 0) { _thr_cancel_enter(curthread); retval = ksem_wait((*sem)->semid); _thr_cancel_leave(curthread, retval != 0); } else { _pthread_testcancel(); _pthread_mutex_lock(&(*sem)->lock); while ((*sem)->count <= 0) { (*sem)->nwaiters++; THR_CLEANUP_PUSH(curthread, decrease_nwaiters, sem); _pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); THR_CLEANUP_POP(curthread, 0); (*sem)->nwaiters--; } (*sem)->count--; _pthread_mutex_unlock(&(*sem)->lock); retval = 0; } return (retval); }
int _sem_destroy(sem_t *sem) { if (sem_check_validity(sem) != 0) return (-1); (*sem)->magic = 0; switch ((*sem)->semid) { case SEMID_LWP: free(*sem); break; case SEMID_FORK: /* memory is left intact */ break; } return (0); }