int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr) { int ret = EINVAL; /* Verify input parameters */ DEBUGASSERT(mutex != NULL); if (mutex != NULL) { /* Make sure that no unexpected context switches occur */ sched_lock(); /* Error out if the mutex is already in an inconsistent state. */ if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) { ret = EOWNERDEAD; } else { /* Take semaphore underlying the mutex. pthread_sem_take * returns zero on success and a positive errno value on failure. */ ret = pthread_sem_take(&mutex->sem, intr); if (ret == OK) { /* Check if the holder of the mutex has terminated without * releasing. In that case, the state of the mutex is * inconsistent and we return EOWNERDEAD. */ if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) { ret = EOWNERDEAD; } /* Add the mutex to the list of mutexes held by this task */ else { pthread_mutex_add(mutex); } } } sched_unlock(); } return ret; }
static void tc_pthread_pthread_sem_take_give(void) { int ret_chk; int get_value; sem_t sem; sem_init(&sem, 0, VAL_THREE); ret_chk = pthread_sem_take(&sem, false); TC_ASSERT_EQ("pthread_sem_take", ret_chk, OK); sem_getvalue(&sem, &get_value); TC_ASSERT_EQ("sem_getvalue", get_value, VAL_TWO); ret_chk = pthread_sem_give(&sem); TC_ASSERT_EQ("pthread_sem_give", ret_chk, OK); sem_getvalue(&sem, &get_value); TC_ASSERT_EQ("sem_getvalue", get_value, VAL_THREE); TC_SUCCESS_RESULT(); }