sched: replace sync pause with async pause for sched_backtrace

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-08-16 18:48:44 +08:00 committed by Xiang Xiao
parent 4b7493901e
commit 7ab27ec1c8

View file

@ -30,6 +30,59 @@
#include "sched.h"
#ifdef CONFIG_ARCH_HAVE_BACKTRACE
/****************************************************************************
* Private Type Declarations
****************************************************************************/
#ifdef CONFIG_SMP
struct backtrace_arg_s
{
pid_t pid;
FAR void **buffer;
int size;
int skip;
cpu_set_t saved_affinity;
uint16_t saved_flags;
bool need_restore;
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int sched_backtrace_handler(FAR void *cookie)
{
FAR struct backtrace_arg_s *arg = cookie;
FAR struct tcb_s *tcb;
irqstate_t flags;
flags = enter_critical_section();
tcb = nxsched_get_tcb(arg->pid);
if (!tcb || tcb->task_state == TSTATE_TASK_INVALID ||
(tcb->flags & TCB_FLAG_EXIT_PROCESSING) != 0)
{
/* There is no TCB with this pid or, if there is, it is not a task. */
leave_critical_section(flags);
return -ESRCH;
}
if (arg->need_restore)
{
tcb->affinity = arg->saved_affinity;
tcb->flags = arg->saved_flags;
}
leave_critical_section(flags);
return up_backtrace(tcb, arg->buffer, arg->size, arg->skip);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -44,7 +97,6 @@
*
****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_BACKTRACE
int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip)
{
FAR struct tcb_s *tcb = this_task();
@ -65,18 +117,36 @@ int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip)
if (tcb->task_state == TSTATE_TASK_RUNNING &&
g_nx_initstate != OSINIT_PANIC)
{
up_cpu_pause(tcb->cpu);
}
#endif
struct backtrace_arg_s arg;
ret = up_backtrace(tcb, buffer, size, skip);
#ifdef CONFIG_SMP
if (tcb->task_state == TSTATE_TASK_RUNNING &&
g_nx_initstate != OSINIT_PANIC)
{
up_cpu_resume(tcb->cpu);
if ((tcb->flags & TCB_FLAG_CPU_LOCKED) != 0)
{
arg.pid = tcb->pid;
arg.need_restore = false;
}
else
{
arg.pid = tcb->pid;
arg.saved_flags = tcb->flags;
arg.saved_affinity = tcb->affinity;
arg.need_restore = true;
tcb->flags |= TCB_FLAG_CPU_LOCKED;
CPU_SET(tcb->cpu, &tcb->affinity);
}
arg.buffer = buffer;
arg.size = size;
arg.skip = skip;
ret = nxsched_smp_call_single(tcb->cpu,
sched_backtrace_handler,
&arg, true);
}
else
#endif
{
ret = up_backtrace(tcb, buffer, size, skip);
}
}
leave_critical_section(flags);