diff --git a/arch/arm/src/kinetis/kinetis_i2c.c b/arch/arm/src/kinetis/kinetis_i2c.c index 88fef0f2fa..6efc2ff09a 100644 --- a/arch/arm/src/kinetis/kinetis_i2c.c +++ b/arch/arm/src/kinetis/kinetis_i2c.c @@ -150,6 +150,7 @@ static inline void kinetis_i2c_sem_post(struct kinetis_i2cdev_s *priv); /* Signal Helper */ static inline void kinetis_i2c_endwait(struct kinetis_i2cdev_s *priv); +static inline void kinetis_i2c_wait(struct kinetis_i2cdev_s *priv); /* I2C helpers */ @@ -368,6 +369,19 @@ static inline void kinetis_i2c_sem_post(struct kinetis_i2cdev_s *priv) sem_post(&priv->mutex); } +/************************************************************************************ + * Name: kinetis_i2c_wait + * + * Description: + * Wait on the signaling semaphore + * + ************************************************************************************/ + +static inline void kinetis_i2c_wait(struct kinetis_i2cdev_s *priv) +{ + sem_wait(&priv->wait); +} + /************************************************************************************ * Name: kinetis_i2c_endwait * @@ -1160,7 +1174,7 @@ static int kinetis_i2c_transfer(struct i2c_master_s *dev, wd_start(priv->timeout, I2C_TIMEOUT, kinetis_i2c_timeout, 1, (uint32_t) priv); - kinetis_i2c_endwait(priv); + kinetis_i2c_wait(priv); wd_cancel(priv->timeout); diff --git a/sched/pthread/pthread_mutexunlock.c b/sched/pthread/pthread_mutexunlock.c index 6a9bab3f8a..be73134883 100644 --- a/sched/pthread/pthread_mutexunlock.c +++ b/sched/pthread/pthread_mutexunlock.c @@ -42,11 +42,45 @@ #include #include #include +#include #include #include #include "pthread/pthread.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_mutex_unlock + * + * Description: + * Return true is the mutex is locked. + * + * Parameters: + * None + * + * Return Value: + * Returns true if the mutex is locked + * + ****************************************************************************/ + +static inline bool pthread_mutex_islocked(FAR struct pthread_mutex_s *mutex) +{ + int semcount = mutex->sem.semcount; + + /* The underlying semaphore should have a count less than 2: + * + * 1 == mutex is unlocked. + * 0 == mutex is locked with no waiters + * -n == mutex is locked with 'n' waiters. + */ + + DEBUGASSERT(semcount < 2); + return semcount < 1; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -80,17 +114,27 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) { - int ret = EINVAL; + int ret = OK; sinfo("mutex=0x%p\n", mutex); DEBUGASSERT(mutex != NULL); + if (mutex == NULL) + { + return -EINVAL; + } /* Make sure the semaphore is stable while we make the following checks. * This all needs to be one atomic action. */ sched_lock(); - if (mutex != NULL) + + /* The unlock operation is only performed if the mutex is actually locked. + * If the mutex is not locked, then SUCCESS will be returned (there is + * no error return value specified for this case). + */ + + if (pthread_mutex_islocked(mutex)) { #if !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) || defined(CONFIG_PTHREAD_MUTEX_TYPES) /* Does the calling thread own the semaphore? If no, should we return