mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
feat(freertos): speed up SMP critical section enter and exit
The critical section port already disables interrupts and reads the core id for the whole section, but spinlock_acquire()/spinlock_release() then disabled interrupts again to the same level and re-read the core id register. Add spinlock_acquire_impl()/spinlock_release_impl(), which take a caller-supplied owner id and skip interrupt management, and reuse them from spinlock_acquire()/spinlock_release() to avoid duplicated code. The Xtensa and RISC-V ports now read the core id once and call the impl variants, removing one core id read and one interrupt mask/restore per critical section enter and exit. Closes https://github.com/espressif/esp-idf/issues/18908
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -25,25 +25,6 @@ extern "C" {
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t xt_utils_get_core_id(void)
|
||||
{
|
||||
/*
|
||||
Note: We depend on SOC_CPU_CORES_NUM instead of XCHAL_HAVE_PRID as some single Xtensa targets (such as ESP32-S2) have
|
||||
the PRID register even though they are single core.
|
||||
*/
|
||||
#if SOC_CPU_CORES_NUM > 1
|
||||
// Read and extract bit 13 of special register PRID
|
||||
uint32_t id;
|
||||
asm volatile (
|
||||
"rsr.prid %0\n"
|
||||
"extui %0,%0,13,1"
|
||||
:"=r"(id));
|
||||
return id;
|
||||
#else
|
||||
return 0;
|
||||
#endif // SOC_CPU_CORES_NUM > 1
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t xt_utils_get_raw_core_id(void)
|
||||
{
|
||||
#if XCHAL_HAVE_PRID
|
||||
@@ -58,6 +39,34 @@ FORCE_INLINE_ATTR __attribute__((pure)) uint32_t xt_utils_get_raw_core_id(void)
|
||||
#endif // XCHAL_HAVE_PRID
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t xt_utils_get_core_id_from_raw(uint32_t raw_core_id)
|
||||
{
|
||||
/*
|
||||
Note: We depend on SOC_CPU_CORES_NUM instead of XCHAL_HAVE_PRID as some single Xtensa targets (such as ESP32-S2) have
|
||||
the PRID register even though they are single core.
|
||||
*/
|
||||
#if SOC_CPU_CORES_NUM > 1
|
||||
// Extract bit 13 of the PRID register value
|
||||
uint32_t id;
|
||||
asm volatile (
|
||||
"extui %0,%1,13,1"
|
||||
:"=r"(id):"r"(raw_core_id));
|
||||
return id;
|
||||
#else
|
||||
(void)raw_core_id;
|
||||
return 0;
|
||||
#endif // SOC_CPU_CORES_NUM > 1
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t xt_utils_get_core_id(void)
|
||||
{
|
||||
#if SOC_CPU_CORES_NUM > 1
|
||||
return xt_utils_get_core_id_from_raw(xt_utils_get_raw_core_id());
|
||||
#else
|
||||
return 0;
|
||||
#endif // SOC_CPU_CORES_NUM > 1
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void *xt_utils_get_sp(void)
|
||||
{
|
||||
void *sp;
|
||||
|
||||
Reference in New Issue
Block a user