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 3, 2024
1 parent af86abc commit caa5791
Show file tree
Hide file tree
Showing 18 changed files with 142 additions and 135 deletions.
2 changes: 0 additions & 2 deletions arch/arm/include/tlsr82/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()) \
Expand Down
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();
}
60 changes: 29 additions & 31 deletions arch/arm/src/arm/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,33 +54,54 @@

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;

/* 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:
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:
Expand All @@ -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);
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
68 changes: 31 additions & 37 deletions arch/arm/src/armv7-a/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
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,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
Expand Down Expand Up @@ -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);
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
57 changes: 30 additions & 27 deletions arch/arm/src/armv7-r/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
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 @@ -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
Expand Down Expand Up @@ -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);
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 caa5791

Please sign in to comment.