fs/drivers: Avoid causing a busy loop in the program due to context switching induced by sem_post.
examples:
There are two threads involved: thread A with a priority of 100 and
thread B with a priority of 101. Here's how they interact:
When thread A releases a semaphore, thread B is scheduled to execute
some code and may reacquire the semaphore. If no other tasks are ready,
thread A will be scheduled to run.
This continuous process can lead to a busy loop.
Thread A: Thread B:
while (nxsem_get_value(&priv->wait, &semcount) >= 0 && <---
semcount <= 0) | 2)context switch
{ 1)contex switch |
nxsem_post(&priv->wait); -------------> run some code and nxsem_wait again
}
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
7a96bee46f
commit
cfd359141f
8 changed files with 40 additions and 17 deletions
|
|
@ -506,11 +506,14 @@ static int i2c_slave_callback(FAR void *arg, i2c_slave_complete_t status,
|
||||||
priv->read_index = 0;
|
priv->read_index = 0;
|
||||||
priv->read_length = length;
|
priv->read_length = length;
|
||||||
|
|
||||||
while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 0)
|
if (nxsem_get_value(&priv->wait, &semcount) >= 0)
|
||||||
|
{
|
||||||
|
while (semcount++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(&priv->wait);
|
nxsem_post(&priv->wait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
events = POLLOUT;
|
events = POLLOUT;
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,13 @@ void ipcc_rxfree_notify(FAR struct ipcc_driver_s *priv)
|
||||||
|
|
||||||
/* Notify all blocked readers that data is available to read */
|
/* Notify all blocked readers that data is available to read */
|
||||||
|
|
||||||
while (nxsem_get_value(&priv->rxsem, &semval) >= 0 && semval <= 0)
|
if (nxsem_get_value(&priv->rxsem, &semval) >= 0)
|
||||||
|
{
|
||||||
|
while (semval++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(&priv->rxsem);
|
nxsem_post(&priv->rxsem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,13 @@ void ipcc_txfree_notify(FAR struct ipcc_driver_s *priv)
|
||||||
|
|
||||||
/* Notify all blocked writers that data is available to write */
|
/* Notify all blocked writers that data is available to write */
|
||||||
|
|
||||||
while (nxsem_get_value(&priv->txsem, &semval) >= 0 && semval <= 0)
|
if (nxsem_get_value(&priv->txsem, &semval) >= 0)
|
||||||
|
{
|
||||||
|
while (semval++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(&priv->txsem);
|
nxsem_post(&priv->txsem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -537,10 +537,13 @@ static void goldfish_pipe_wake(FAR struct goldfish_pipe_s *pipe,
|
||||||
FAR sem_t *sem = is_write ? &pipe->wait_for_write : &pipe->wait_for_read;
|
FAR sem_t *sem = is_write ? &pipe->wait_for_write : &pipe->wait_for_read;
|
||||||
int sval;
|
int sval;
|
||||||
|
|
||||||
while (nxsem_get_value(sem, &sval) >= 0 && sval <= 0)
|
if (nxsem_get_value(sem, &sval) >= 0)
|
||||||
|
{
|
||||||
|
while (sval++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(sem);
|
nxsem_post(sem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int goldfish_pipe_interrupt(int irq, FAR void *context, FAR void *arg)
|
static int goldfish_pipe_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,13 @@ static void pipecommon_wakeup(FAR sem_t *sem)
|
||||||
{
|
{
|
||||||
int sval;
|
int sval;
|
||||||
|
|
||||||
while (nxsem_get_value(sem, &sval) == OK && sval <= 0)
|
if (nxsem_get_value(sem, &sval) >= 0)
|
||||||
|
{
|
||||||
|
while (sval++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(sem);
|
nxsem_post(sem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -742,10 +742,13 @@ static void spi_slave_notify(FAR struct spi_slave_dev_s *dev,
|
||||||
poll_notify(&priv->fds, 1, POLLERR);
|
poll_notify(&priv->fds, 1, POLLERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nxsem_get_value(&priv->wait, &semcnt) == 0 && semcnt <= 0)
|
if (nxsem_get_value(&priv->wait, &semcnt) >= 0)
|
||||||
|
{
|
||||||
|
while (semcnt++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(&priv->wait);
|
nxsem_post(&priv->wait);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -561,12 +561,14 @@ static void bt_slip_unack_handle(FAR struct sliphci_s *priv)
|
||||||
{
|
{
|
||||||
int semcount;
|
int semcount;
|
||||||
|
|
||||||
while (nxsem_get_value(&priv->sem, &semcount) >= 0 &&
|
if (nxsem_get_value(&priv->sem, &semcount) >= 0)
|
||||||
semcount <= 0)
|
{
|
||||||
|
while (semcount++ <= 0)
|
||||||
{
|
{
|
||||||
nxsem_post(&priv->sem);
|
nxsem_post(&priv->sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
to_remove--;
|
to_remove--;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,10 +289,13 @@ static void inotify_queue_event(FAR struct inotify_device_s *dev, int wd,
|
||||||
|
|
||||||
poll_notify(dev->fds, CONFIG_FS_NOTIFY_FD_POLLWAITERS, POLLIN);
|
poll_notify(dev->fds, CONFIG_FS_NOTIFY_FD_POLLWAITERS, POLLIN);
|
||||||
|
|
||||||
while (nxsem_get_value(&dev->sem, &semcnt) == 0 && semcnt <= 1)
|
if (nxsem_get_value(&dev->sem, &semcnt) >= 0)
|
||||||
|
{
|
||||||
|
while (semcnt++ <= 1)
|
||||||
{
|
{
|
||||||
nxsem_post(&dev->sem);
|
nxsem_post(&dev->sem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue