mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
wireless/bluetooth: Soften use of enter_critical_sectino() which is a performance hog in SMP configurations. Replace with spin_lock_irqsave() in most cases. That is the same for single core CPUs, but much more efficient in SMP configurations. And better, repace with sched_lock() if there is really no necessity to disable interrupts too.
This commit is contained in:
@@ -242,7 +242,7 @@ FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type,
|
|||||||
* then try the list of messages reserved for interrupt handlers
|
* then try the list of messages reserved for interrupt handlers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section(); /* Always necessary in SMP mode */
|
flags = spin_lock_irqsave(); /* Always necessary in SMP mode */
|
||||||
if (up_interrupt_context())
|
if (up_interrupt_context())
|
||||||
{
|
{
|
||||||
#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE
|
#if CONFIG_BLUETOOTH_BUFFER_PREALLOC > CONFIG_BLUETOOTH_BUFFER_IRQRESERVE
|
||||||
@@ -253,7 +253,7 @@ FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type,
|
|||||||
buf = g_buf_free;
|
buf = g_buf_free;
|
||||||
g_buf_free = buf->flink;
|
g_buf_free = buf->flink;
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(flags);
|
||||||
pool = POOL_BUFFER_GENERAL;
|
pool = POOL_BUFFER_GENERAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -266,13 +266,13 @@ FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type,
|
|||||||
buf = g_buf_free_irq;
|
buf = g_buf_free_irq;
|
||||||
g_buf_free_irq = buf->flink;
|
g_buf_free_irq = buf->flink;
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(flags);
|
||||||
pool = POOL_BUFFER_IRQ;
|
pool = POOL_BUFFER_IRQ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(flags);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -422,10 +422,10 @@ void bt_buf_release(FAR struct bt_buf_s *buf)
|
|||||||
* list from interrupt handlers.
|
* list from interrupt handlers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave();
|
||||||
buf->flink = g_buf_free;
|
buf->flink = g_buf_free;
|
||||||
g_buf_free = buf;
|
g_buf_free = buf;
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(flags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -441,10 +441,10 @@ void bt_buf_release(FAR struct bt_buf_s *buf)
|
|||||||
* list from interrupt handlers.
|
* list from interrupt handlers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave();
|
||||||
buf->flink = g_buf_free_irq;
|
buf->flink = g_buf_free_irq;
|
||||||
g_buf_free_irq = buf;
|
g_buf_free_irq = buf;
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(flags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -50,10 +50,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sched.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/irq.h>
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/kthread.h>
|
#include <nuttx/kthread.h>
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
@@ -1518,20 +1518,23 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct timespec abstime;
|
struct timespec abstime;
|
||||||
irqstate_t flags;
|
|
||||||
|
|
||||||
/* Wait for the response to the command. An I/O error will be
|
/* Wait for the response to the command. An I/O error will be
|
||||||
* declared if the response does not occur within the timeout
|
* declared if the response does not occur within the timeout
|
||||||
* interval.
|
* interval.
|
||||||
*
|
*
|
||||||
* Get the current time. Not that we must be in critical section here
|
* REVISIT: The cause of the timeout could be a failure to receive a
|
||||||
* so that we can be assured that there will be no context switches
|
* response to a sent frame or, perhaps, a failure to send the frame.
|
||||||
|
* Should there also be logic to flush any unsent Tx packets?
|
||||||
|
*
|
||||||
|
* Get the current time. Not that we lock the scheduler here so that
|
||||||
|
* we can be assured that there will be no context switches will occur
|
||||||
* between the time that we calculate the delay time and until we get
|
* between the time that we calculate the delay time and until we get
|
||||||
* to the wait.
|
* to the wait.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
sched_lock();
|
||||||
ret = clock_gettime(CLOCK_REALTIME, &abstime);
|
ret = clock_gettime(CLOCK_REALTIME, &abstime);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
/* Add the offset to the time in the future */
|
/* Add the offset to the time in the future */
|
||||||
@@ -1560,7 +1563,7 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf,
|
|||||||
while (ret == -EINTR);
|
while (ret == -EINTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
sched_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indicate failure if we failed to get the response */
|
/* Indicate failure if we failed to get the response */
|
||||||
|
|||||||
@@ -662,7 +662,7 @@ static int btnet_ifdown(FAR struct net_driver_s *netdev)
|
|||||||
|
|
||||||
/* Disable interruption */
|
/* Disable interruption */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave();
|
||||||
|
|
||||||
/* Cancel the TX poll timer and TX timeout timers */
|
/* Cancel the TX poll timer and TX timeout timers */
|
||||||
|
|
||||||
@@ -676,7 +676,7 @@ static int btnet_ifdown(FAR struct net_driver_s *netdev)
|
|||||||
/* Mark the device "down" */
|
/* Mark the device "down" */
|
||||||
|
|
||||||
priv->bd_bifup = false;
|
priv->bd_bifup = false;
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user