arm/rtl8720c: Critical Section Optimization.

Replace critical_section with spinlock or mutex.
The benefits of doing this are:

1. It makes the code logic clearer, with different resources protected by different locks.

2. It improves system responsiveness and avoids contention issues caused by acquiring the same large lock.

Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
This commit is contained in:
wangzhi16 2025-06-20 21:17:31 +08:00 committed by Xiang Xiao
parent a724a5f4f4
commit 44f2f6f8f1
6 changed files with 43 additions and 37 deletions

View file

@ -30,6 +30,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/partition.h>
#include <nuttx/spinlock.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -131,6 +132,8 @@ static const struct partition_s ptable[5] =
},
};
static spinlock_t g_lock = SP_UNLOCKED;
/****************************************************************************
* Private Functions
****************************************************************************/
@ -138,7 +141,7 @@ static const struct partition_s ptable[5] =
static irqstate_t flash_resource_lock(void)
{
irqstate_t state;
state = enter_critical_section();
state = spin_lock_irqsave(&g_lock);
icache_disable();
dcache_disable();
return state;
@ -149,7 +152,7 @@ static void flash_resource_unlock(irqstate_t state)
dcache_enable();
icache_enable();
icache_invalidate();
leave_critical_section(state);
spin_unlock_irqrestore(&g_lock, state);
}
static int ameba_flash_erase(struct mtd_dev_s *dev,

View file

@ -33,7 +33,7 @@
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/arch.h>
#include <nuttx/serial/serial.h>
#include <nuttx/fs/ioctl.h>
@ -107,6 +107,7 @@ struct ameba_s
bool flow; /* flow control (RTS/CTS) enabled */
#endif
#endif
spinlock_t lock; /* Ensure mutually exclusive access */
};
/****************************************************************************
@ -213,6 +214,7 @@ static struct ameba_s g_uart0priv =
.flow = true,
#endif
#endif
.lock = SP_UNLOCKED,
};
static uart_dev_t g_uart0port =
@ -251,6 +253,7 @@ static struct ameba_s g_uart1priv =
.flow = true,
#endif
#endif
.lock = SP_UNLOCKED,
};
static uart_dev_t g_uart1port =
@ -289,6 +292,7 @@ static struct ameba_s g_uart2priv =
.flow = true,
#endif
#endif
.lock = SP_UNLOCKED,
};
static uart_dev_t g_uart2port =
@ -327,6 +331,7 @@ static struct ameba_s g_uart3priv =
.flow = true,
#endif
#endif
.lock = SP_UNLOCKED,
};
static uart_dev_t g_uart3port =
@ -753,7 +758,7 @@ static int ameba_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
}
flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
cfsetispeed(termiosp, priv->baud);
termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) |
((priv->parity == 1) ? PARODD : 0);
@ -778,7 +783,7 @@ static int ameba_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
}
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
break;
@ -792,7 +797,7 @@ static int ameba_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
}
flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
switch (termiosp->c_cflag & CSIZE)
{
case CS5:
@ -826,7 +831,7 @@ static int ameba_ioctl(struct file *filep, int cmd, unsigned long arg)
priv->flow = (termiosp->c_cflag & CRTSCTS) != 0;
#endif
ameba_setup(dev);
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
break;

View file

@ -26,6 +26,7 @@
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/spinlock.h>
#include <nuttx/timers/watchdog.h>
#include <stdint.h>
#include <sys/types.h>
@ -53,6 +54,7 @@ struct ameba_lowerhalf_s
bool started; /* true: The watchdog timer has
* been started
*/
spinlock_t lock; /* Ensure mutually exclusive access */
};
/****************************************************************************
@ -113,11 +115,11 @@ static int ameba_start(struct watchdog_lowerhalf_s *lower)
{
struct ameba_lowerhalf_s *priv = (struct ameba_lowerhalf_s *)lower;
irqstate_t flags;
flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
priv->started = true;
priv->lastreset = clock_systime_ticks();
hal_misc_wdt_enable();
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}
@ -140,12 +142,12 @@ static int ameba_stop(struct watchdog_lowerhalf_s *lower)
{
struct ameba_lowerhalf_s *priv = (struct ameba_lowerhalf_s *)lower;
irqstate_t flags;
flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
hal_misc_wdt_disable();
priv->started = false;
priv->timeout = 0;
priv->lastreset = 0;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}
@ -176,10 +178,10 @@ static int ameba_keepalive(struct watchdog_lowerhalf_s *lower)
/* Reload the WDT timer */
flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
priv->lastreset = clock_systime_ticks();
hal_misc_wdt_refresh();
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}
@ -254,10 +256,10 @@ static int ameba_settimeout(struct watchdog_lowerhalf_s *lower,
{
struct ameba_lowerhalf_s *priv = (struct ameba_lowerhalf_s *)lower;
irqstate_t flags;
flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
priv->timeout = timeout;
hal_misc_wdt_init(timeout * 1000);
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}
@ -287,6 +289,7 @@ void ameba_wdt_initialize(void)
/* Initialize the driver state structure. */
priv->ops = &g_wdgops;
spin_lock_init(&priv->lock);
watchdog_register(CONFIG_WATCHDOG_DEVPATH,
(struct watchdog_lowerhalf_s *)priv);
}

View file

@ -28,6 +28,7 @@
#include <nuttx/mqueue.h>
#include <nuttx/semaphore.h>
#include <nuttx/signal.h>
#include <nuttx/spinlock.h>
#include <nuttx/syslog/syslog.h>
/****************************************************************************
@ -52,24 +53,23 @@ int __wrap_printf(const char *fmt, ...)
/* stdio.h Wrapper End */
static int uxcriticalnesting = 0;
static rspinlock_t g_lock = RSPINLOCK_INITIALIZER;
static irqstate_t g_flags = 0;
/* Critical Operation Start */
void save_and_cli(void)
{
enter_critical_section();
uxcriticalnesting++;
irqstate_t flags = rspin_lock_irqsave(&g_lock);
if (!rspin_lock_is_recursive(&g_lock))
{
g_flags = flags;
}
}
void restore_flags(void)
{
ASSERT(uxcriticalnesting);
uxcriticalnesting--;
if (uxcriticalnesting == 0)
{
leave_critical_section(0);
}
rspin_unlock_irqrestore(&g_lock, g_flags);
}
void rtw_enter_critical(void **plock, unsigned long *pirql)
@ -871,21 +871,14 @@ uint32_t rtw_end_of_queue_search(struct list_head *head,
/* Device lock Wrapper Start */
static uint32_t mutex_init;
static atomic_t mutex_init;
static void *device_mutex[5];
static void device_mutex_init(uint32_t device)
{
irqstate_t status;
if (!(mutex_init & (1 << device)))
if (atomic_fetch_or(&mutex_init, (1 << device)) & (1 << device) == 0)
{
status = enter_critical_section();
if (!(mutex_init & (1 << device)))
{
rtw_mutex_init(&device_mutex[device]);
mutex_init |= (1 << device);
}
leave_critical_section(status);
rtw_mutex_init(&device_mutex[device]);
}
}

View file

@ -29,6 +29,7 @@
#include <nuttx/config.h>
#include <nuttx/semaphore.h>
#include <nuttx/mutex.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
#include <nuttx/net/netdev.h>
@ -86,6 +87,7 @@ struct amebaz_dev_s
rtw_scan_result_t scan_data[AMEBAZ_SCAN_AP_COUNT];
unsigned int scan_count;
unsigned char country[2];
mutex_t lock;
};
int amebaz_wl_start_scan(struct amebaz_dev_s *priv,

View file

@ -296,14 +296,13 @@ static int amebaz_ifdown(struct net_driver_s *dev)
{
int ret = 0;
struct amebaz_dev_s *priv = (struct amebaz_dev_s *)dev->d_private;
irqstate_t flags;
if (priv->devnum == 0 && rltk_wlan_running(1))
{
printf("must ifdown wlan 1 first\r\n");
return ERROR;
}
flags = enter_critical_section();
nxmutex_lock(&priv->lock);
if (IFF_IS_UP(dev->d_flags))
{
if (priv->curr)
@ -333,7 +332,7 @@ static int amebaz_ifdown(struct net_driver_s *dev)
}
}
leave_critical_section(flags);
nxmutex_unlock(&priv->lock);
return ret;
}
@ -343,6 +342,7 @@ int amebaz_netdev_register(struct amebaz_dev_s *priv)
dev->d_ifup = amebaz_ifup;
dev->d_ifdown = amebaz_ifdown;
dev->d_txavail = amebaz_txavail;
nxmutex_init(priv->lock);
#ifdef CONFIG_NETDEV_IOCTL
dev->d_ioctl = amebaz_ioctl;
#endif