This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 2b22ee03d6a44f82c94a557e5c0c41932718c5d1 Author: hujun5 <[email protected]> AuthorDate: Thu Nov 21 16:48:42 2024 +0800 arm: remove g_running_tasks[this_cpu()] = NULL reason: We hope to keep g_running_tasks valid forever. Signed-off-by: hujun5 <[email protected]> --- arch/arm/include/tlsr82/irq.h | 2 -- arch/arm/src/arm/arm_sigdeliver.c | 1 - arch/arm/src/arm/arm_syscall.c | 60 +++++++++++++++---------------- arch/arm/src/armv6-m/arm_doirq.c | 6 +++- arch/arm/src/armv6-m/arm_sigdeliver.c | 2 +- arch/arm/src/armv7-a/arm_sigdeliver.c | 1 - arch/arm/src/armv7-a/arm_syscall.c | 68 ++++++++++++++++------------------- arch/arm/src/armv7-m/arm_doirq.c | 6 +++- arch/arm/src/armv7-m/arm_sigdeliver.c | 1 - arch/arm/src/armv7-r/arm_sigdeliver.c | 1 - arch/arm/src/armv7-r/arm_syscall.c | 57 +++++++++++++++-------------- arch/arm/src/armv8-m/arm_doirq.c | 6 +++- arch/arm/src/armv8-m/arm_sigdeliver.c | 2 +- arch/arm/src/armv8-r/arm_sigdeliver.c | 1 - arch/arm/src/armv8-r/arm_syscall.c | 57 +++++++++++++++-------------- arch/arm/src/common/arm_exit.c | 2 +- arch/arm/src/common/arm_internal.h | 2 ++ arch/arm/src/tlsr82/chip.h | 2 ++ 18 files changed, 142 insertions(+), 135 deletions(-) diff --git a/arch/arm/include/tlsr82/irq.h b/arch/arm/include/tlsr82/irq.h index 529c5692aa..115f9f14b6 100644 --- a/arch/arm/include/tlsr82/irq.h +++ b/arch/arm/include/tlsr82/irq.h @@ -283,8 +283,6 @@ static inline_function void up_set_interrupt_context(bool flag) #endif } -#define arm_fullcontextrestore() tc32_fullcontextrestore(this_task()->xcp.regs) - #define up_switch_context(tcb, rtcb) \ do { \ if (!up_interrupt_context()) \ diff --git a/arch/arm/src/arm/arm_sigdeliver.c b/arch/arm/src/arm/arm_sigdeliver.c index a76152b535..a0ab5f36fb 100644 --- a/arch/arm/src/arm/arm_sigdeliver.c +++ b/arch/arm/src/arm/arm_sigdeliver.c @@ -97,7 +97,6 @@ void arm_sigdeliver(void) board_autoled_off(LED_SIGNAL); - g_running_tasks[this_cpu()] = NULL; rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); } diff --git a/arch/arm/src/arm/arm_syscall.c b/arch/arm/src/arm/arm_syscall.c index 7443e27c1d..3903159bfd 100644 --- a/arch/arm/src/arm/arm_syscall.c +++ b/arch/arm/src/arm/arm_syscall.c @@ -54,7 +54,8 @@ uint32_t *arm_syscall(uint32_t *regs) { - struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + int cpu = this_cpu(); + struct tcb_s **running_task = &g_running_tasks[cpu]; FAR struct tcb_s *tcb = this_task(); uint32_t cmd; @@ -62,12 +63,9 @@ uint32_t *arm_syscall(uint32_t *regs) DEBUGASSERT(!up_interrupt_context()); - if (*running_task != NULL) - { - (*running_task)->xcp.regs = regs; - } - - /* Set irq flag */ + /* Current regs non-zero indicates that we are processing an interrupt; + * current_regs is also used to manage interrupt level context switches. + */ up_set_interrupt_context(true); @@ -75,12 +73,35 @@ uint32_t *arm_syscall(uint32_t *regs) cmd = regs[REG_R0]; + /* if cmd == SYS_restore_context (*running_task)->xcp.regs is valid + * should not be overwriten + */ + + if (cmd != SYS_restore_context) + { + (*running_task)->xcp.regs = regs; + } + /* Handle the SVCall according to the command in R0 */ switch (cmd) { - case SYS_restore_context: case SYS_switch_context: + + /* Update scheduler parameters */ + + nxsched_resume_scheduler(tcb); + + case SYS_restore_context: + nxsched_suspend_scheduler(*running_task); + *running_task = tcb; + + /* Restore the cpu lock */ + + restore_critical_section(tcb, cpu); +#ifdef CONFIG_ARCH_ADDRENV + addrenv_switch(tcb); +#endif break; default: @@ -92,29 +113,6 @@ uint32_t *arm_syscall(uint32_t *regs) break; } - if (*running_task != tcb) - { -#ifdef CONFIG_ARCH_ADDRENV - /* Make sure that the address environment for the previously - * running task is closed down gracefully (data caches dump, - * MMU flushed) and set up the address environment for the new - * thread at the head of the ready-to-run list. - */ - - addrenv_switch(NULL); -#endif - /* Update scheduler parameters */ - - nxsched_suspend_scheduler(*running_task); - nxsched_resume_scheduler(tcb); - - *running_task = tcb; - - /* Restore the cpu lock */ - - restore_critical_section(tcb, this_cpu()); - } - /* Set irq flag */ up_set_interrupt_context(false); diff --git a/arch/arm/src/armv6-m/arm_doirq.c b/arch/arm/src/armv6-m/arm_doirq.c index 9c9e78d3cf..e3e6383e48 100644 --- a/arch/arm/src/armv6-m/arm_doirq.c +++ b/arch/arm/src/armv6-m/arm_doirq.c @@ -59,7 +59,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) struct tcb_s **running_task = &g_running_tasks[this_cpu()]; FAR struct tcb_s *tcb; - if (*running_task != NULL) + /* This judgment proves that (*running_task)->xcp.regs + * is invalid, and we can safely overwrite it. + */ + + if (!(NVIC_IRQ_SVCALL == irq && regs[REG_R0] == SYS_restore_context)) { (*running_task)->xcp.regs = regs; } diff --git a/arch/arm/src/armv6-m/arm_sigdeliver.c b/arch/arm/src/armv6-m/arm_sigdeliver.c index 5fd3f44463..73ad65e14a 100644 --- a/arch/arm/src/armv6-m/arm_sigdeliver.c +++ b/arch/arm/src/armv6-m/arm_sigdeliver.c @@ -162,7 +162,7 @@ retry: leave_critical_section((uint16_t)regs[REG_PRIMASK]); rtcb->irqcount--; #endif - g_running_tasks[this_cpu()] = NULL; + rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); UNUSED(regs); diff --git a/arch/arm/src/armv7-a/arm_sigdeliver.c b/arch/arm/src/armv7-a/arm_sigdeliver.c index 5c0e058a4e..5de0caa880 100644 --- a/arch/arm/src/armv7-a/arm_sigdeliver.c +++ b/arch/arm/src/armv7-a/arm_sigdeliver.c @@ -161,7 +161,6 @@ retry: rtcb->irqcount--; #endif - g_running_tasks[this_cpu()] = NULL; rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); UNUSED(regs); diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index f31e403155..df7f68d1ff 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -159,7 +159,8 @@ static void dispatch_syscall(void) uint32_t *arm_syscall(uint32_t *regs) { - struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + int cpu = this_cpu(); + struct tcb_s **running_task = &g_running_tasks[cpu]; struct tcb_s *tcb = this_task(); uint32_t cmd; #ifdef CONFIG_BUILD_KERNEL @@ -170,12 +171,9 @@ uint32_t *arm_syscall(uint32_t *regs) DEBUGASSERT(!up_interrupt_context()); - if (*running_task != NULL) - { - (*running_task)->xcp.regs = regs; - } - - /* Set irq flag */ + /* Current regs non-zero indicates that we are processing an interrupt; + * current_regs is also used to manage interrupt level context switches. + */ up_set_interrupt_context(true); @@ -183,6 +181,15 @@ uint32_t *arm_syscall(uint32_t *regs) cmd = regs[REG_R0]; + /* if cmd == SYS_restore_context (*running_task)->xcp.regs is valid + * should not be overwriten + */ + + if (cmd != SYS_restore_context) + { + (*running_task)->xcp.regs = regs; + } + /* The SVCall software interrupt is called with R0 = system call command * and R1..R7 = variable number of arguments depending on the system call. */ @@ -255,8 +262,24 @@ uint32_t *arm_syscall(uint32_t *regs) } break; #endif - case SYS_restore_context: + case SYS_switch_context: + + /* Update scheduler parameters */ + + nxsched_resume_scheduler(tcb); + + case SYS_restore_context: + nxsched_suspend_scheduler(*running_task); + *running_task = tcb; + + /* Restore the cpu lock */ + + restore_critical_section(tcb, cpu); + regs = tcb->xcp.regs; +#ifdef CONFIG_ARCH_ADDRENV + addrenv_switch(tcb); +#endif break; /* R0=SYS_task_start: This a user task start @@ -522,35 +545,6 @@ uint32_t *arm_syscall(uint32_t *regs) break; } - if (*running_task != tcb) - { -#ifdef CONFIG_ARCH_ADDRENV - /* Make sure that the address environment for the previously - * running task is closed down gracefully (data caches dump, - * MMU flushed) and set up the address environment for the new - * thread at the head of the ready-to-run list. - */ - - addrenv_switch(NULL); -#endif - - /* Update scheduler parameters */ - - nxsched_suspend_scheduler(*running_task); - nxsched_resume_scheduler(tcb); - - /* Record the new "running" task. g_running_tasks[] is only used by - * assertion logic for reporting crashes. - */ - - *running_task = tcb; - - /* Restore the cpu lock */ - - restore_critical_section(tcb, this_cpu()); - regs = tcb->xcp.regs; - } - /* Report what happened */ dump_syscall("Exit", cmd, regs); diff --git a/arch/arm/src/armv7-m/arm_doirq.c b/arch/arm/src/armv7-m/arm_doirq.c index 9989437e47..dcbdd9dc12 100644 --- a/arch/arm/src/armv7-m/arm_doirq.c +++ b/arch/arm/src/armv7-m/arm_doirq.c @@ -59,7 +59,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) struct tcb_s **running_task = &g_running_tasks[this_cpu()]; FAR struct tcb_s *tcb; - if (*running_task != NULL) + /* This judgment proves that (*running_task)->xcp.regs + * is invalid, and we can safely overwrite it. + */ + + if (!(NVIC_IRQ_SVCALL == irq && regs[REG_R0] == SYS_restore_context)) { (*running_task)->xcp.regs = regs; } diff --git a/arch/arm/src/armv7-m/arm_sigdeliver.c b/arch/arm/src/armv7-m/arm_sigdeliver.c index 5642e82623..3d617ea46a 100644 --- a/arch/arm/src/armv7-m/arm_sigdeliver.c +++ b/arch/arm/src/armv7-m/arm_sigdeliver.c @@ -175,7 +175,6 @@ retry: rtcb->irqcount--; #endif - g_running_tasks[this_cpu()] = NULL; rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); UNUSED(regs); diff --git a/arch/arm/src/armv7-r/arm_sigdeliver.c b/arch/arm/src/armv7-r/arm_sigdeliver.c index 009ad90657..bd715470cd 100644 --- a/arch/arm/src/armv7-r/arm_sigdeliver.c +++ b/arch/arm/src/armv7-r/arm_sigdeliver.c @@ -158,7 +158,6 @@ retry: rtcb->irqcount--; #endif - g_running_tasks[this_cpu()] = NULL; rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); UNUSED(regs); diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c index 315a6f42d4..179b27baae 100644 --- a/arch/arm/src/armv7-r/arm_syscall.c +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -156,7 +156,8 @@ static void dispatch_syscall(void) uint32_t *arm_syscall(uint32_t *regs) { - struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + int cpu = this_cpu(); + struct tcb_s **running_task = &g_running_tasks[cpu]; FAR struct tcb_s *tcb = this_task(); uint32_t cmd; #ifdef CONFIG_BUILD_PROTECTED @@ -167,12 +168,9 @@ uint32_t *arm_syscall(uint32_t *regs) DEBUGASSERT(!up_interrupt_context()); - if (*running_task != NULL) - { - (*running_task)->xcp.regs = regs; - } - - /* Set irq flag */ + /* Current regs non-zero indicates that we are processing an interrupt; + * current_regs is also used to manage interrupt level context switches. + */ up_set_interrupt_context(true); @@ -180,6 +178,15 @@ uint32_t *arm_syscall(uint32_t *regs) cmd = regs[REG_R0]; + /* if cmd == SYS_restore_context (*running_task)->xcp.regs is valid + * should not be overwriten + */ + + if (cmd != SYS_restore_context) + { + (*running_task)->xcp.regs = regs; + } + /* The SVCall software interrupt is called with R0 = system call command * and R1..R7 = variable number of arguments depending on the system call. */ @@ -253,8 +260,23 @@ uint32_t *arm_syscall(uint32_t *regs) break; #endif - case SYS_restore_context: case SYS_switch_context: + + /* Update scheduler parameters */ + + nxsched_resume_scheduler(tcb); + + case SYS_restore_context: + nxsched_suspend_scheduler(*running_task); + *running_task = tcb; + + /* Restore the cpu lock */ + + restore_critical_section(tcb, cpu); + regs = tcb->xcp.regs; +#ifdef CONFIG_ARCH_ADDRENV + addrenv_switch(tcb); +#endif break; /* R0=SYS_task_start: This a user task start @@ -520,25 +542,6 @@ uint32_t *arm_syscall(uint32_t *regs) break; } - if (*running_task != tcb) - { - /* Update scheduler parameters */ - - nxsched_suspend_scheduler(*running_task); - nxsched_resume_scheduler(tcb); - - /* Record the new "running" task. g_running_tasks[] is only used by - * assertion logic for reporting crashes. - */ - - *running_task = tcb; - - /* Restore the cpu lock */ - - restore_critical_section(tcb, this_cpu()); - regs = tcb->xcp.regs; - } - /* Report what happened */ dump_syscall("Exit", cmd, regs); diff --git a/arch/arm/src/armv8-m/arm_doirq.c b/arch/arm/src/armv8-m/arm_doirq.c index 3cd28ae298..55183573a5 100644 --- a/arch/arm/src/armv8-m/arm_doirq.c +++ b/arch/arm/src/armv8-m/arm_doirq.c @@ -70,7 +70,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) struct tcb_s **running_task = &g_running_tasks[this_cpu()]; FAR struct tcb_s *tcb; - if (*running_task != NULL) + /* This judgment proves that (*running_task)->xcp.regs + * is invalid, and we can safely overwrite it. + */ + + if (!(NVIC_IRQ_SVCALL == irq && regs[REG_R0] == SYS_restore_context)) { (*running_task)->xcp.regs = regs; } diff --git a/arch/arm/src/armv8-m/arm_sigdeliver.c b/arch/arm/src/armv8-m/arm_sigdeliver.c index aff8738235..43d72e35a8 100644 --- a/arch/arm/src/armv8-m/arm_sigdeliver.c +++ b/arch/arm/src/armv8-m/arm_sigdeliver.c @@ -174,7 +174,7 @@ retry: #endif rtcb->irqcount--; #endif - g_running_tasks[this_cpu()] = NULL; + rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); UNUSED(regs); diff --git a/arch/arm/src/armv8-r/arm_sigdeliver.c b/arch/arm/src/armv8-r/arm_sigdeliver.c index 5e4015e986..17fbc7b198 100644 --- a/arch/arm/src/armv8-r/arm_sigdeliver.c +++ b/arch/arm/src/armv8-r/arm_sigdeliver.c @@ -156,7 +156,6 @@ retry: rtcb->irqcount--; #endif - g_running_tasks[this_cpu()] = NULL; rtcb->xcp.regs = rtcb->xcp.saved_regs; arm_fullcontextrestore(); UNUSED(regs); diff --git a/arch/arm/src/armv8-r/arm_syscall.c b/arch/arm/src/armv8-r/arm_syscall.c index e478aafecf..d003166840 100644 --- a/arch/arm/src/armv8-r/arm_syscall.c +++ b/arch/arm/src/armv8-r/arm_syscall.c @@ -156,7 +156,8 @@ static void dispatch_syscall(void) uint32_t *arm_syscall(uint32_t *regs) { - struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + int cpu = this_cpu(); + struct tcb_s **running_task = &g_running_tasks[cpu]; FAR struct tcb_s *tcb = this_task(); uint32_t cmd; #ifdef CONFIG_BUILD_PROTECTED @@ -167,12 +168,9 @@ uint32_t *arm_syscall(uint32_t *regs) DEBUGASSERT(!up_interrupt_context()); - if (*running_task != NULL) - { - (*running_task)->xcp.regs = regs; - } - - /* Set irq flag */ + /* Current regs non-zero indicates that we are processing an interrupt; + * current_regs is also used to manage interrupt level context switches. + */ up_set_interrupt_context(true); @@ -180,6 +178,15 @@ uint32_t *arm_syscall(uint32_t *regs) cmd = regs[REG_R0]; + /* if cmd == SYS_restore_context (*running_task)->xcp.regs is valid + * should not be overwriten + */ + + if (cmd != SYS_restore_context) + { + (*running_task)->xcp.regs = regs; + } + /* The SVCall software interrupt is called with R0 = system call command * and R1..R7 = variable number of arguments depending on the system call. */ @@ -253,8 +260,23 @@ uint32_t *arm_syscall(uint32_t *regs) break; #endif - case SYS_restore_context: case SYS_switch_context: + + /* Update scheduler parameters */ + + nxsched_resume_scheduler(tcb); + + case SYS_restore_context: + nxsched_suspend_scheduler(*running_task); + *running_task = tcb; + + /* Restore the cpu lock */ + + restore_critical_section(tcb, cpu); + regs = tcb->xcp.regs; +#ifdef CONFIG_ARCH_ADDRENV + addrenv_switch(tcb); +#endif break; /* R0=SYS_task_start: This a user task start @@ -520,25 +542,6 @@ uint32_t *arm_syscall(uint32_t *regs) break; } - if (*running_task != tcb) - { - /* Update scheduler parameters */ - - nxsched_suspend_scheduler(*running_task); - nxsched_resume_scheduler(tcb); - - /* Record the new "running" task. g_running_tasks[] is only used by - * assertion logic for reporting crashes. - */ - - *running_task = tcb; - - /* Restore the cpu lock */ - - restore_critical_section(tcb, this_cpu()); - regs = tcb->xcp.regs; - } - /* Report what happened */ dump_syscall("Exit", cmd, regs); diff --git a/arch/arm/src/common/arm_exit.c b/arch/arm/src/common/arm_exit.c index fa49dc5fed..1b6cafbf80 100644 --- a/arch/arm/src/common/arm_exit.c +++ b/arch/arm/src/common/arm_exit.c @@ -60,7 +60,7 @@ void up_exit(int status) /* Scheduler parameters will update inside syscall */ - g_running_tasks[this_cpu()] = NULL; + g_running_tasks[this_cpu()] = this_task(); /* Then switch contexts */ diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h index b72c256a83..c7e4243cae 100644 --- a/arch/arm/src/common/arm_internal.h +++ b/arch/arm/src/common/arm_internal.h @@ -33,6 +33,8 @@ # include <sys/types.h> # include <stdint.h> # include <syscall.h> + +# include "chip.h" #endif /**************************************************************************** diff --git a/arch/arm/src/tlsr82/chip.h b/arch/arm/src/tlsr82/chip.h index dfc81861bd..18be19cf38 100644 --- a/arch/arm/src/tlsr82/chip.h +++ b/arch/arm/src/tlsr82/chip.h @@ -33,6 +33,8 @@ #define ARMV6M_PERIPHERAL_INTERRUPTS NR_IRQS +#define arm_fullcontextrestore() tc32_fullcontextrestore(this_task()->xcp.regs) + /* Include the memory map file. * Other chip hardware files should then include this file for the proper * setup.
