sched/spinlock: Add configuration to record busywait.

Add configuration "CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT", which can record the busy waiting time to get spinlock or enter critical section.

Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
This commit is contained in:
wangzhi16
2024-11-11 09:44:28 +08:00
committed by Donny(董九柱)
parent bb562cf8bf
commit 3116c19efc
7 changed files with 263 additions and 0 deletions
+4
View File
@@ -150,6 +150,10 @@
# define CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION -1
#endif
#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT
# define CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT -1
#endif
#ifndef CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ
# define CONFIG_SCHED_CRITMONITOR_MAXTIME_IRQ -1
#endif
+13
View File
@@ -701,6 +701,14 @@ struct tcb_s
void *crit_max_caller; /* Caller of max critical section */
#endif
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT >= 0
clock_t busywait_start; /* Time when thread busywait */
clock_t busywait_max; /* Max time of busywait */
clock_t busywait_total; /* Total time of busywait */
void *busywait_caller; /* Caller of busywait */
void *busywait_max_caller; /* Caller of max busywait */
#endif
/* State save areas *******************************************************/
/* The form and content of these fields are platform-specific. */
@@ -821,6 +829,11 @@ EXTERN clock_t g_preemp_max[CONFIG_SMP_NCPUS];
EXTERN clock_t g_crit_max[CONFIG_SMP_NCPUS];
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT >= 0
EXTERN clock_t g_busywait_max[CONFIG_SMP_NCPUS];
EXTERN clock_t g_busywait_total[CONFIG_SMP_NCPUS];
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT >= 0 */
/* g_running_tasks[] holds a references to the running task for each CPU.
* It is valid only when up_interrupt_context() returns true.
*/
+22
View File
@@ -66,6 +66,12 @@ void sched_note_spinlock_unlock(FAR volatile spinlock_t *spinlock);
# define sched_note_spinlock_unlock(spinlock)
#endif
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT >= 0
void nxsched_critmon_busywait(bool state, FAR void *caller);
#else
# define nxsched_critmon_busywait(state, caller)
#endif
/****************************************************************************
* Public Data Types
****************************************************************************/
@@ -223,10 +229,18 @@ static inline_function void spin_lock(FAR volatile spinlock_t *lock)
sched_note_spinlock_lock(lock);
/* If CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT >= 0, count busy-waiting. */
nxsched_critmon_busywait(true, return_address(0));
/* Lock without trace note */
spin_lock_notrace(lock);
/* Get the lock, end counting busy-waiting */
nxsched_critmon_busywait(false, return_address(0));
/* Notify that we have the spinlock */
sched_note_spinlock_locked(lock);
@@ -988,6 +1002,8 @@ void rspin_restorelock(FAR rspinlock_t *lock, uint16_t count)
static inline_function void read_lock(FAR volatile rwlock_t *lock)
{
nxsched_critmon_busywait(true, return_address(0));
while (true)
{
int old = atomic_read(lock);
@@ -1004,6 +1020,8 @@ static inline_function void read_lock(FAR volatile rwlock_t *lock)
}
UP_DMB();
nxsched_critmon_busywait(false, return_address(0));
}
/****************************************************************************
@@ -1106,6 +1124,8 @@ static inline_function void read_unlock(FAR volatile rwlock_t *lock)
static inline_function void write_lock(FAR volatile rwlock_t *lock)
{
nxsched_critmon_busywait(true, return_address(0));
while (true)
{
int zero = RW_SP_UNLOCKED;
@@ -1119,6 +1139,8 @@ static inline_function void write_lock(FAR volatile rwlock_t *lock)
}
UP_DMB();
nxsched_critmon_busywait(false, return_address(0));
}
/****************************************************************************