Fix some odd logic in CC3000 semaphore handling. Noted by Vladimir Komendantskiy

This commit is contained in:
Gregory Nutt 2016-02-10 09:50:28 -06:00
parent 2c0ad2564f
commit bf8120d51d
2 changed files with 25 additions and 72 deletions

View File

@ -211,27 +211,23 @@ uint8_t spi_readCommand[] = READ_COMMAND;
* *
****************************************************************************/ ****************************************************************************/
static int cc3000_devtake(FAR struct cc3000_dev_s *priv) static inline void cc3000_devtake(FAR struct cc3000_dev_s *priv)
{ {
int rv;
/* Take the semaphore (perhaps waiting) */ /* Take the semaphore (perhaps waiting) */
while ((rv = sem_wait(&priv->devsem)) != 0) while (sem_wait(&priv->devsem) < 0)
{ {
/* The only case that an error should occur here is if the wait was awakened /* The only case that an error should occur here is if the wait was
* by a signal. * awakened by a signal.
*/ */
DEBUGASSERT(rv == OK || errno == EINTR); DEBUGASSERT(errno == EINTR);
}
} }
return rv; static inline void cc3000_devgive(FAR struct cc3000_dev_s *priv)
}
static inline int cc3000_devgive(FAR struct cc3000_dev_s *priv)
{ {
return sem_post(&priv->devsem); (void)sem_post(&priv->devsem);
} }
/**************************************************************************** /****************************************************************************
@ -354,27 +350,16 @@ static int cc3000_wait(FAR struct cc3000_dev_s *priv, sem_t *psem)
/* Wait on first psem to become signaled */ /* Wait on first psem to become signaled */
ret = sem_wait(psem); ret = sem_wait(psem);
if (ret >= 0)
{
/* Yes... then retake the mutual exclusion semaphore */
ret = cc3000_devtake(priv);
}
sched_unlock();
/* Was the semaphore wait successful? Did we successful re-take the
* mutual exclusion semaphore?
*/
if (ret < 0) if (ret < 0)
{ {
/* No.. One of the two sem_wait's failed. */ return -errno;
ret = -errno;
} }
return ret; /* Then retake the mutual exclusion semaphore */
cc3000_devtake(priv);
sched_unlock();
return OK;
} }
/**************************************************************************** /****************************************************************************
@ -820,11 +805,7 @@ static int cc3000_open(FAR struct file *filep)
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
if (ret < 0)
{
return -ret;
}
/* Increment the reference count */ /* Increment the reference count */
@ -988,7 +969,6 @@ static int cc3000_close(FAR struct file *filep)
{ {
FAR struct inode *inode; FAR struct inode *inode;
FAR struct cc3000_dev_s *priv; FAR struct cc3000_dev_s *priv;
int ret;
#ifdef CONFIG_CC3000_MT #ifdef CONFIG_CC3000_MT
int s; int s;
#endif #endif
@ -1005,11 +985,7 @@ static int cc3000_close(FAR struct file *filep)
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
if (ret < 0)
{
return -EINTR;
}
/* Decrement the reference count unless it would decrement a negative /* Decrement the reference count unless it would decrement a negative
* value. When the count decrements to zero, there are no further * value. When the count decrements to zero, there are no further
@ -1086,13 +1062,7 @@ static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len)
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
if (ret < 0)
{
nread = -errno;
goto errout_without_sem;
}
/* Verify that the caller has provided a buffer large enough to receive /* Verify that the caller has provided a buffer large enough to receive
* the maximum data. * the maximum data.
@ -1152,7 +1122,7 @@ static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len)
{ {
/* Yes... then retake the mutual exclusion semaphore */ /* Yes... then retake the mutual exclusion semaphore */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
} }
/* Was the semaphore wait successful? Did we successful re-take the /* Was the semaphore wait successful? Did we successful re-take the
@ -1239,15 +1209,7 @@ static ssize_t cc3000_write(FAR struct file *filep, FAR const char *usrbuffer, s
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
if (ret < 0)
{
/* This should only happen if the wait was canceled by an signal */
ndbg("sem_wait: %d\n", errno);
nwritten = -errno;
goto errout_without_sem;
}
/* Figure out the total length of the packet in order to figure out if there is padding or not */ /* Figure out the total length of the packet in order to figure out if there is padding or not */
@ -1352,13 +1314,7 @@ static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
/* Get exclusive access to the driver data structure */ /* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
if (ret < 0)
{
/* This should only happen if the wait was canceled by an signal */
return -errno;
}
/* Process the IOCTL by command */ /* Process the IOCTL by command */
@ -1463,13 +1419,7 @@ static int cc3000_poll(FAR struct file *filep, FAR struct pollfd *fds,
/* Are we setting up the poll? Or tearing it down? */ /* Are we setting up the poll? Or tearing it down? */
ret = cc3000_devtake(priv); cc3000_devtake(priv);
if (ret < 0)
{
/* This should only happen if the wait was canceled by an signal */
return -errno;
}
if (setup) if (setup)
{ {

View File

@ -139,7 +139,10 @@ void spinlock(FAR struct spinlock_s *lock)
# warning Missing logic # warning Missing logic
#endif #endif
/* Take the lock */ /* Take the lock. REVISIT: We should set an indication in the TCB
* that the thread is spinning. This might be useful in determining
* some scheduling actions?
*/
while (up_testset(&lock->sp_lock) == SP_LOCKED) while (up_testset(&lock->sp_lock) == SP_LOCKED)
{ {