Skip to content

Commit

Permalink
arm: remove g_running_tasks[this_cpu()] = NULL
Browse files Browse the repository at this point in the history
reason:
We hope to keep g_running_tasks valid forever.

Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 committed Dec 2, 2024
1 parent 99bc691 commit 6f44449
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 79 deletions.
1 change: 0 additions & 1 deletion arch/arm/src/arm/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
41 changes: 27 additions & 14 deletions arch/arm/src/arm/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,51 @@ uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb = this_task();
bool switch_context = false;
uint32_t cmd;

/* Nested interrupts are not supported */

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);

/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */

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:
switch_context = true;

/* Update scheduler parameters */

nxsched_resume_scheduler(tcb);
break;
case SYS_switch_context:
switch_context = true;

/* Update scheduler parameters */

nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
*running_task = tcb;
break;

default:
Expand All @@ -92,7 +112,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}

if (*running_task != tcb)
if (switch_context)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
Expand All @@ -103,13 +123,6 @@ uint32_t *arm_syscall(uint32_t *regs)

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());
Expand Down
6 changes: 5 additions & 1 deletion arch/arm/src/armv6-m/arm_doirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/src/armv6-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void arm_sigdeliver(void)
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);
Expand Down
1 change: 0 additions & 1 deletion arch/arm/src/armv7-a/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ void arm_sigdeliver(void)
rtcb->irqcount--;
#endif

g_running_tasks[this_cpu()] = NULL;
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
Expand Down
46 changes: 28 additions & 18 deletions arch/arm/src/armv7-a/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
struct tcb_s *tcb = this_task();
bool switch_context = false;
uint32_t cmd;
#ifdef CONFIG_BUILD_KERNEL
uint32_t cpsr;
Expand All @@ -170,19 +171,25 @@ 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);

/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */

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.
*/
Expand Down Expand Up @@ -255,8 +262,22 @@ uint32_t *arm_syscall(uint32_t *regs)
}
break;
#endif

case SYS_restore_context:
switch_context = true;

/* Update scheduler parameters */

nxsched_resume_scheduler(tcb);
break;
case SYS_switch_context:
switch_context = true;

/* Update scheduler parameters */

nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
*running_task = tcb;
break;

/* R0=SYS_task_start: This a user task start
Expand Down Expand Up @@ -522,7 +543,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}

if (*running_task != tcb)
if (switch_context)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
Expand All @@ -534,17 +555,6 @@ uint32_t *arm_syscall(uint32_t *regs)
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());
Expand Down
6 changes: 5 additions & 1 deletion arch/arm/src/armv7-m/arm_doirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion arch/arm/src/armv7-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ void arm_sigdeliver(void)
rtcb->irqcount--;
#endif

g_running_tasks[this_cpu()] = NULL;
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
Expand Down
1 change: 0 additions & 1 deletion arch/arm/src/armv7-r/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ void arm_sigdeliver(void)
rtcb->irqcount--;
#endif

g_running_tasks[this_cpu()] = NULL;
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
Expand Down
45 changes: 27 additions & 18 deletions arch/arm/src/armv7-r/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb = this_task();
bool switch_context = false;
uint32_t cmd;
#ifdef CONFIG_BUILD_PROTECTED
uint32_t cpsr;
Expand All @@ -167,19 +168,25 @@ 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);

/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */

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.
*/
Expand Down Expand Up @@ -254,7 +261,20 @@ uint32_t *arm_syscall(uint32_t *regs)
#endif

case SYS_restore_context:
switch_context = true;

/* Update scheduler parameters */

nxsched_resume_scheduler(tcb);
break;
case SYS_switch_context:
switch_context = true;

/* Update scheduler parameters */

nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
*running_task = tcb;
break;

/* R0=SYS_task_start: This a user task start
Expand Down Expand Up @@ -520,19 +540,8 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}

if (*running_task != tcb)
if (switch_context)
{
/* 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());
Expand Down
6 changes: 5 additions & 1 deletion arch/arm/src/armv8-m/arm_doirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/src/armv8-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void arm_sigdeliver(void)
#endif
rtcb->irqcount--;
#endif
g_running_tasks[this_cpu()] = NULL;

rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
Expand Down
1 change: 0 additions & 1 deletion arch/arm/src/armv8-r/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ void arm_sigdeliver(void)
rtcb->irqcount--;
#endif

g_running_tasks[this_cpu()] = NULL;
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
Expand Down
Loading

0 comments on commit 6f44449

Please sign in to comment.