You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2024/03/01 12:05:06 UTC
(nuttx) branch master updated (954bffcbd7 -> 2241969e5a)
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from 954bffcbd7 sched/tls: inline group info in flat mode to improve performance
new 85bc84f5c5 arm64: remove the CONFIG_DEBUG_SCHED_INFO=y
new 27ef7576ff arm64/defconfig: improve the arm64 defconfig
new 2241969e5a SMP: fix crash when switch to new task which is still running
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/arm/src/armv7-a/arm_cpupause.c | 76 ++++++++++++++----
arch/arm/src/armv7-r/arm_cpupause.c | 76 ++++++++++++++----
arch/arm/src/cxd56xx/cxd56_cpupause.c | 90 ++++++++++++++++------
arch/arm/src/lc823450/lc823450_cpupause.c | 82 +++++++++++++++-----
arch/arm/src/rp2040/rp2040_cpupause.c | 80 ++++++++++++++-----
arch/arm/src/sam34/sam4cm_cpupause.c | 76 ++++++++++++++----
arch/arm64/src/common/arm64_cpupause.c | 74 ++++++++++++++----
arch/risc-v/src/common/riscv_cpupause.c | 81 ++++++++++++++-----
arch/sim/src/sim/sim_smpsignal.c | 81 +++++++++++++------
arch/sparc/src/s698pm/s698pm_cpupause.c | 81 ++++++++++++++-----
arch/xtensa/src/common/xtensa_cpupause.c | 83 +++++++++++++++-----
.../fvp-v8r/fvp-armv8r/configs/citest/defconfig | 1 -
.../fvp-armv8r/configs/citest_smp/defconfig | 1 -
.../arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig | 1 -
.../fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig | 1 -
boards/arm64/imx8/imx8qm-mek/configs/nsh/defconfig | 1 -
.../qemu/qemu-armv8a/configs/citest/defconfig | 1 -
.../qemu/qemu-armv8a/configs/citest_smp/defconfig | 1 -
.../arm64/qemu/qemu-armv8a/configs/nsh/defconfig | 1 -
.../qemu/qemu-armv8a/configs/nsh_gicv2/defconfig | 1 -
.../qemu/qemu-armv8a/configs/nsh_smp/defconfig | 9 ++-
.../qemu-armv8a/configs/nsh_smp_tickless/defconfig | 1 -
.../qemu/qemu-armv8a/configs/sotest/defconfig | 1 -
include/nuttx/arch.h | 43 +++++++++++
sched/irq/irq_csection.c | 12 +++
25 files changed, 730 insertions(+), 225 deletions(-)
(nuttx) 02/03: arm64/defconfig: improve the arm64 defconfig
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 27ef7576ff87ea0b80fc532f61c13138a4ca24e8
Author: ligd <li...@xiaomi.com>
AuthorDate: Wed Jan 31 12:35:22 2024 +0800
arm64/defconfig: improve the arm64 defconfig
Signed-off-by: ligd <li...@xiaomi.com>
---
boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
index 1d65af633b..02d70382bb 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
@@ -5,6 +5,7 @@
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
+# CONFIG_NSH_DISABLE_MW is not set
CONFIG_ARCH="arm64"
CONFIG_ARCH_ARM64=y
CONFIG_ARCH_BOARD="qemu-armv8a"
@@ -14,6 +15,7 @@ CONFIG_ARCH_CHIP_QEMU=y
CONFIG_ARCH_CHIP_QEMU_A53=y
CONFIG_ARCH_EARLY_PRINT=y
CONFIG_ARCH_INTERRUPTSTACK=8192
+CONFIG_ARCH_STACKDUMP=y
CONFIG_ARM64_STRING_FUNCTION=y
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
@@ -27,6 +29,7 @@ CONFIG_DEFAULT_TASK_STACKSIZE=16384
CONFIG_DEV_ZERO=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXPERIMENTAL=y
+CONFIG_FRAME_POINTER=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_FS_ROMFS=y
@@ -37,6 +40,7 @@ CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
+CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_PTHREAD_STACK_MIN=16384
CONFIG_RAMLOG=y
@@ -45,9 +49,11 @@ CONFIG_RAM_START=0x40000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SMP=y
+CONFIG_SMP_NCPUS=2
CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2022
@@ -57,10 +63,10 @@ CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TASKSET=y
CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_OSPERF=y
CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_OSTEST_STACKSIZE=16384
CONFIG_TESTING_SMP=y
-CONFIG_TICKET_SPINLOCK=y
CONFIG_UART1_BASE=0x9000000
CONFIG_UART1_IRQ=33
CONFIG_UART1_PL011=y
(nuttx) 01/03: arm64: remove the CONFIG_DEBUG_SCHED_INFO=y
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 85bc84f5c5182826bf572f3ef27a15fc742f0b8c
Author: ligd <li...@xiaomi.com>
AuthorDate: Tue Feb 20 13:42:11 2024 +0800
arm64: remove the CONFIG_DEBUG_SCHED_INFO=y
Signed-off-by: ligd <li...@xiaomi.com>
---
boards/arm64/fvp-v8r/fvp-armv8r/configs/citest/defconfig | 1 -
boards/arm64/fvp-v8r/fvp-armv8r/configs/citest_smp/defconfig | 1 -
boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig | 1 -
boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig | 1 -
boards/arm64/imx8/imx8qm-mek/configs/nsh/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/citest/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/citest_smp/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/nsh_smp_tickless/defconfig | 1 -
boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig | 1 -
12 files changed, 12 deletions(-)
diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest/defconfig b/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest/defconfig
index 9d26c77b42..2decb87bcc 100644
--- a/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest/defconfig
+++ b/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest/defconfig
@@ -20,7 +20,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest_smp/defconfig b/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest_smp/defconfig
index b69c196495..e7a74f367b 100644
--- a/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest_smp/defconfig
+++ b/boards/arm64/fvp-v8r/fvp-armv8r/configs/citest_smp/defconfig
@@ -20,7 +20,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig
index 34c8ecec69..4d6ad5db68 100644
--- a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig
+++ b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig
@@ -21,7 +21,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig
index 8284fac1f8..2aa238cb90 100644
--- a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig
+++ b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig
@@ -21,7 +21,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/imx8/imx8qm-mek/configs/nsh/defconfig b/boards/arm64/imx8/imx8qm-mek/configs/nsh/defconfig
index 77c1e320d2..f7408fe9f0 100644
--- a/boards/arm64/imx8/imx8qm-mek/configs/nsh/defconfig
+++ b/boards/arm64/imx8/imx8qm-mek/configs/nsh/defconfig
@@ -20,7 +20,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/citest/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/citest/defconfig
index 561df15522..43afdbef74 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/citest/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/citest/defconfig
@@ -19,7 +19,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/citest_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/citest_smp/defconfig
index 2d7623cc4e..a4f51ab8c1 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/citest_smp/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/citest_smp/defconfig
@@ -19,7 +19,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=16384
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
index 102b2e3cc9..aa5334edb3 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
@@ -23,7 +23,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig
index 4a09582c94..f233e388e6 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig
@@ -20,7 +20,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
index c9c4ef0862..1d65af633b 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
@@ -21,7 +21,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=16384
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp_tickless/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp_tickless/defconfig
index 5aa5dd1f5c..29b48dcc80 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp_tickless/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp_tickless/defconfig
@@ -20,7 +20,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=16384
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig
index 4ecdcd2e57..db830a4acd 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig
@@ -28,7 +28,6 @@ CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SCHED=y
CONFIG_DEBUG_SCHED_ERROR=y
-CONFIG_DEBUG_SCHED_INFO=y
CONFIG_DEBUG_SCHED_WARN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
(nuttx) 03/03: SMP: fix crash when switch to new task which is still running
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 2241969e5ada2eaafee38ab6de6457aa15c8402c
Author: ligd <li...@xiaomi.com>
AuthorDate: Thu Feb 22 10:44:56 2024 +0800
SMP: fix crash when switch to new task which is still running
cpu0 thread0: cpu1:
sched_yield()
nxsched_set_priority()
nxsched_running_setpriority()
nxsched_reprioritize_rtr()
nxsched_add_readytorun()
up_cpu_pause()
IRQ enter
arm64_pause_handler()
enter_critical_section() begin
up_cpu_paused() pick thread0
arm64_restorestate() set thread0 tcb->xcp.regs to CURRENT_REGS
up_switch_context()
thread0 -> thread1
arm64_syscall()
case SYS_switch_context
change thread0 tcb->xcp.regs
restore_critical_section()
enter_critical_section() done
leave_critical_section()
IRQ leave with restore CURRENT_REGS
ERROR !!!
Reason:
As descript above, cpu0 swith task: thread0 -> thread1, and the
syscall() execute slowly, this time cpu1 pick thread0 to run at
up_cpu_paused(). Then cpu0 syscall execute, cpu1 IRQ leave error.
Resolve:
Move arm64_restorestate() after enter_critical_section() done
This is a continued fix with:
https://github.com/apache/nuttx/pull/6833
Signed-off-by: ligd <li...@xiaomi.com>
---
arch/arm/src/armv7-a/arm_cpupause.c | 76 ++++++++++++++++++++------
arch/arm/src/armv7-r/arm_cpupause.c | 76 ++++++++++++++++++++------
arch/arm/src/cxd56xx/cxd56_cpupause.c | 90 ++++++++++++++++++++++---------
arch/arm/src/lc823450/lc823450_cpupause.c | 82 ++++++++++++++++++++--------
arch/arm/src/rp2040/rp2040_cpupause.c | 80 ++++++++++++++++++++-------
arch/arm/src/sam34/sam4cm_cpupause.c | 76 ++++++++++++++++++++------
arch/arm64/src/common/arm64_cpupause.c | 74 ++++++++++++++++++++-----
arch/risc-v/src/common/riscv_cpupause.c | 81 +++++++++++++++++++++-------
arch/sim/src/sim/sim_smpsignal.c | 81 ++++++++++++++++++++--------
arch/sparc/src/s698pm/s698pm_cpupause.c | 81 +++++++++++++++++++++-------
arch/xtensa/src/common/xtensa_cpupause.c | 83 ++++++++++++++++++++--------
include/nuttx/arch.h | 43 +++++++++++++++
sched/irq/irq_csection.c | 12 +++++
13 files changed, 723 insertions(+), 212 deletions(-)
diff --git a/arch/arm/src/armv7-a/arm_cpupause.c b/arch/arm/src/armv7-a/arm_cpupause.c
index ed098c4ba7..4c7b6a71dd 100644
--- a/arch/arm/src/armv7-a/arm_cpupause.c
+++ b/arch/arm/src/armv7-a/arm_cpupause.c
@@ -85,7 +85,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -94,16 +94,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -111,7 +103,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -131,6 +123,38 @@ int up_cpu_paused(int cpu)
arm_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Release the g_cpu_paused spinlock to synchronize with the
* requesting CPU.
*/
@@ -147,11 +171,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* This CPU has been resumed. Restore the exception context of the TCB at
- * the (new) head of the assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
- tcb = this_task();
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -168,8 +212,6 @@ int up_cpu_paused(int cpu)
*/
arm_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
diff --git a/arch/arm/src/armv7-r/arm_cpupause.c b/arch/arm/src/armv7-r/arm_cpupause.c
index 921b1f0f39..3e8102d6f5 100644
--- a/arch/arm/src/armv7-r/arm_cpupause.c
+++ b/arch/arm/src/armv7-r/arm_cpupause.c
@@ -85,7 +85,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -94,16 +94,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -111,7 +103,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -131,6 +123,38 @@ int up_cpu_paused(int cpu)
arm_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Release the g_cpu_paused spinlock to synchronize with the
* requesting CPU.
*/
@@ -147,11 +171,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* This CPU has been resumed. Restore the exception context of the TCB at
- * the (new) head of the assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
- tcb = this_task();
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -168,8 +212,6 @@ int up_cpu_paused(int cpu)
*/
arm_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
diff --git a/arch/arm/src/cxd56xx/cxd56_cpupause.c b/arch/arm/src/cxd56xx/cxd56_cpupause.c
index 476c684331..2e1a6a9542 100644
--- a/arch/arm/src/cxd56xx/cxd56_cpupause.c
+++ b/arch/arm/src/cxd56xx/cxd56_cpupause.c
@@ -167,7 +167,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -176,16 +176,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -193,15 +185,8 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
- /* Fistly, check if this IPI is to enable/disable IRQ */
-
- if (handle_irqreq(cpu))
- {
- return OK;
- }
-
struct tcb_s *tcb = this_task();
/* Update scheduler parameters */
@@ -220,6 +205,45 @@ int up_cpu_paused(int cpu)
arm_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
+ /* Fistly, check if this IPI is to enable/disable IRQ */
+
+ if (handle_irqreq(cpu))
+ {
+ return OK;
+ }
+
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -230,11 +254,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
- tcb = this_task();
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -251,8 +295,6 @@ int up_cpu_paused(int cpu)
*/
arm_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
diff --git a/arch/arm/src/lc823450/lc823450_cpupause.c b/arch/arm/src/lc823450/lc823450_cpupause.c
index d00c939ef2..fc5a246157 100644
--- a/arch/arm/src/lc823450/lc823450_cpupause.c
+++ b/arch/arm/src/lc823450/lc823450_cpupause.c
@@ -95,7 +95,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -104,16 +104,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -121,7 +113,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -141,6 +133,38 @@ int up_cpu_paused(int cpu)
arm_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -151,11 +175,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
- tcb = this_task();
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -173,10 +217,6 @@ int up_cpu_paused(int cpu)
arm_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
-
- spin_unlock(&g_cpu_resumed[cpu]);
-
return OK;
}
@@ -307,7 +347,7 @@ int up_cpu_pause(int cpu)
* called. g_cpu_paused will be unlocked in any case.
*/
- return 0;
+ return OK;
}
/****************************************************************************
@@ -357,5 +397,5 @@ int up_cpu_resume(int cpu)
spin_unlock(&g_cpu_resumed[cpu]);
- return 0;
+ return OK;
}
diff --git a/arch/arm/src/rp2040/rp2040_cpupause.c b/arch/arm/src/rp2040/rp2040_cpupause.c
index 2d74d77511..44e100ef41 100644
--- a/arch/arm/src/rp2040/rp2040_cpupause.c
+++ b/arch/arm/src/rp2040/rp2040_cpupause.c
@@ -135,7 +135,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -144,16 +144,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -161,7 +153,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -181,6 +173,38 @@ int up_cpu_paused(int cpu)
arm_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -191,11 +215,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
- tcb = this_task();
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -212,8 +256,6 @@ int up_cpu_paused(int cpu)
*/
arm_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
@@ -357,7 +399,7 @@ int up_cpu_pause(int cpu)
* called. g_cpu_paused will be unlocked in any case.
*/
- return 0;
+ return OK;
}
/****************************************************************************
@@ -406,7 +448,7 @@ int up_cpu_resume(int cpu)
spin_lock(&g_cpu_resumed[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
- return 0;
+ return OK;
}
/****************************************************************************
diff --git a/arch/arm/src/sam34/sam4cm_cpupause.c b/arch/arm/src/sam34/sam4cm_cpupause.c
index f81902bd9b..dc80b3cc9d 100644
--- a/arch/arm/src/sam34/sam4cm_cpupause.c
+++ b/arch/arm/src/sam34/sam4cm_cpupause.c
@@ -97,7 +97,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -106,16 +106,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -123,7 +115,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -143,6 +135,38 @@ int up_cpu_paused(int cpu)
arm_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -153,11 +177,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
- tcb = this_task();
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -174,8 +218,6 @@ int up_cpu_paused(int cpu)
*/
arm_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
diff --git a/arch/arm64/src/common/arm64_cpupause.c b/arch/arm64/src/common/arm64_cpupause.c
index 0d7acefee8..943b56c421 100644
--- a/arch/arm64/src/common/arm64_cpupause.c
+++ b/arch/arm64/src/common/arm64_cpupause.c
@@ -84,7 +84,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -93,16 +93,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -110,7 +102,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -130,6 +122,38 @@ int up_cpu_paused(int cpu)
arm64_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Release the g_cpu_paused spinlock to synchronize with the
* requesting CPU.
*/
@@ -150,7 +174,31 @@ int up_cpu_paused(int cpu)
* the (new) head of the assigned task list.
*/
- tcb = this_task();
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -167,8 +215,6 @@ int up_cpu_paused(int cpu)
*/
arm64_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
diff --git a/arch/risc-v/src/common/riscv_cpupause.c b/arch/risc-v/src/common/riscv_cpupause.c
index 8f5c292433..730fc55170 100644
--- a/arch/risc-v/src/common/riscv_cpupause.c
+++ b/arch/risc-v/src/common/riscv_cpupause.c
@@ -85,7 +85,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -94,16 +94,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -111,7 +103,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -131,6 +123,38 @@ int up_cpu_paused(int cpu)
riscv_savecontext(tcb);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -141,11 +165,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
- tcb = this_task();
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -163,9 +207,6 @@ int up_cpu_paused(int cpu)
riscv_restorecontext(tcb);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
-
return OK;
}
@@ -280,7 +321,7 @@ int up_cpu_pause(int cpu)
* called. g_cpu_paused will be unlocked in any case.
*/
- return 0;
+ return OK;
}
/****************************************************************************
@@ -330,5 +371,5 @@ int up_cpu_resume(int cpu)
spin_unlock(&g_cpu_resumed[cpu]);
- return 0;
+ return OK;
}
diff --git a/arch/sim/src/sim/sim_smpsignal.c b/arch/sim/src/sim/sim_smpsignal.c
index 0f9ba526da..aef103b194 100644
--- a/arch/sim/src/sim/sim_smpsignal.c
+++ b/arch/sim/src/sim/sim_smpsignal.c
@@ -128,7 +128,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -137,16 +137,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -154,9 +146,9 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
- struct tcb_s *tcb = current_task(cpu);
+ struct tcb_s *tcb = this_task();
/* Update scheduler parameters */
@@ -174,6 +166,38 @@ int up_cpu_paused(int cpu)
sim_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -184,16 +208,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
- tcb = current_task(cpu);
+ return OK;
+}
- /* The way that we handle signals in the simulation is kind of a
- * kludge. This would be unsafe in a truly multi-threaded,
- * interrupt driven environment.
- */
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -214,8 +253,6 @@ int up_cpu_paused(int cpu)
*/
sim_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
return OK;
}
diff --git a/arch/sparc/src/s698pm/s698pm_cpupause.c b/arch/sparc/src/s698pm/s698pm_cpupause.c
index 16449cabf8..3e7101a66d 100644
--- a/arch/sparc/src/s698pm/s698pm_cpupause.c
+++ b/arch/sparc/src/s698pm/s698pm_cpupause.c
@@ -85,7 +85,7 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
@@ -94,16 +94,8 @@ bool up_cpu_pausereq(int cpu)
* pause operation in other contexts where the interrupt cannot be taken
* in order to avoid deadlocks.
*
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
- *
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -111,7 +103,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -131,6 +123,38 @@ int up_cpu_paused(int cpu)
sparc_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -141,11 +165,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
- tcb = this_task();
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -163,9 +207,6 @@ int up_cpu_paused(int cpu)
sparc_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
-
return OK;
}
@@ -283,7 +324,7 @@ int up_cpu_pause(int cpu)
* called. g_cpu_paused will be unlocked in any case.
*/
- return 0;
+ return OK;
}
/****************************************************************************
@@ -333,5 +374,5 @@ int up_cpu_resume(int cpu)
spin_unlock(&g_cpu_resumed[cpu]);
- return 0;
+ return OK;
}
diff --git a/arch/xtensa/src/common/xtensa_cpupause.c b/arch/xtensa/src/common/xtensa_cpupause.c
index 9a8697f3cf..12cfcfa549 100644
--- a/arch/xtensa/src/common/xtensa_cpupause.c
+++ b/arch/xtensa/src/common/xtensa_cpupause.c
@@ -70,25 +70,17 @@ bool up_cpu_pausereq(int cpu)
}
/****************************************************************************
- * Name: up_cpu_paused
+ * Name: up_cpu_paused_save
*
* Description:
* Handle a pause request from another CPU. Normally, this logic is
* executed from interrupt handling logic within the architecture-specific
- * However, it is sometimes necessary to perform the pending pause
- * operation in other contexts where the interrupt cannot be taken in
- * order to avoid deadlocks.
- *
- * This function performs the following operations:
- *
- * 1. It saves the current task state at the head of the current assigned
- * task list.
- * 2. It waits on a spinlock, then
- * 3. Returns from interrupt, restoring the state of the new task at the
- * head of the ready to run list.
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
*
* Input Parameters:
- * cpu - The index of the CPU to be paused
+ * None
*
* Returned Value:
* On success, OK is returned. Otherwise, a negated errno value indicating
@@ -96,7 +88,7 @@ bool up_cpu_pausereq(int cpu)
*
****************************************************************************/
-int up_cpu_paused(int cpu)
+int up_cpu_paused_save(void)
{
struct tcb_s *tcb = this_task();
@@ -116,6 +108,38 @@ int up_cpu_paused(int cpu)
xtensa_savestate(tcb->xcp.regs);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending pause
+ * operation in other contexts where the interrupt cannot be taken in
+ * order to avoid deadlocks.
+ *
+ * This function performs the following operations:
+ *
+ * 1. It saves the current task state at the head of the current assigned
+ * task list.
+ * 2. It waits on a spinlock, then
+ * 3. Returns from interrupt, restoring the state of the new task at the
+ * head of the ready to run list.
+ *
+ * Input Parameters:
+ * cpu - The index of the CPU to be paused
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused(int cpu)
+{
/* Wait for the spinlock to be released */
spin_unlock(&g_cpu_paused[cpu]);
@@ -126,11 +150,31 @@ int up_cpu_paused(int cpu)
spin_lock(&g_cpu_wait[cpu]);
- /* Restore the exception context of the tcb at the (new) head of the
- * assigned task list.
- */
+ spin_unlock(&g_cpu_wait[cpu]);
+ spin_unlock(&g_cpu_resumed[cpu]);
- tcb = this_task();
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+int up_cpu_paused_restore(void)
+{
+ struct tcb_s *tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
@@ -148,9 +192,6 @@ int up_cpu_paused(int cpu)
xtensa_restorestate(tcb->xcp.regs);
- spin_unlock(&g_cpu_wait[cpu]);
- spin_unlock(&g_cpu_resumed[cpu]);
-
return OK;
}
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 785b113b94..2abbdf0b75 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -2256,6 +2256,29 @@ int up_cpu_pause(int cpu);
bool up_cpu_pausereq(int cpu);
#endif
+/****************************************************************************
+ * Name: up_cpu_paused_save
+ *
+ * Description:
+ * Handle a pause request from another CPU. Normally, this logic is
+ * executed from interrupt handling logic within the architecture-specific
+ * However, it is sometimes necessary to perform the pending
+ * pause operation in other contexts where the interrupt cannot be taken
+ * in order to avoid deadlocks.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMP
+int up_cpu_paused_save(void);
+#endif
+
/****************************************************************************
* Name: up_cpu_paused
*
@@ -2287,6 +2310,26 @@ bool up_cpu_pausereq(int cpu);
int up_cpu_paused(int cpu);
#endif
+/****************************************************************************
+ * Name: up_cpu_paused_restore
+ *
+ * Description:
+ * Restore the state of the CPU after it was paused via up_cpu_pause(),
+ * and resume normal tasking.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, OK is returned. Otherwise, a negated errno value indicating
+ * the nature of the failure is returned.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMP
+int up_cpu_paused_restore(void);
+#endif
+
/****************************************************************************
* Name: up_cpu_resume
*
diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c
index 799182960d..0c804c7460 100644
--- a/sched/irq/irq_csection.c
+++ b/sched/irq/irq_csection.c
@@ -252,6 +252,8 @@ try_again:
else
{
+ int paused = false;
+
/* Make sure that the g_cpu_irqset was not already set
* by previous logic on this CPU that was executed by the
* interrupt handler. We know that the bit in g_cpu_irqset
@@ -273,7 +275,13 @@ try_again_in_irq:
* handling the pause request now.
*/
+ if (!paused)
+ {
+ up_cpu_paused_save();
+ }
+
DEBUGVERIFY(up_cpu_paused(cpu));
+ paused = true;
/* NOTE: As the result of up_cpu_paused(cpu), this CPU
* might set g_cpu_irqset in nxsched_resume_scheduler()
@@ -305,6 +313,10 @@ try_again_in_irq:
spin_setbit(&g_cpu_irqset, cpu, &g_cpu_irqsetlock,
&g_cpu_irqlock);
+ if (paused)
+ {
+ up_cpu_paused_restore();
+ }
}
}
else