Skip to content

Commit

Permalink
[libcpu] arm64: Add hardware thread_self support
Browse files Browse the repository at this point in the history
This patch introduces hardware-based thread self-identification
for the AArch64 architecture. It optimizes thread management by
using hardware registers to store and access the current thread's
pointer, reducing overhead and improving overall performance.

Changes include:
- Added `ARCH_USING_HW_THREAD_SELF` configuration option.
- Modified `rtdef.h`, `rtsched.h` to conditionally include
  `critical_switch_flag` based on the new config.
- Updated context management in `context_gcc.S`, `cpuport.h`
  to support hardware-based thread self.
- Enhanced `scheduler_mp.c` and `thread.c` to leverage the new
  hardware thread self feature.

These modifications ensure better scheduling and thread handling,
particularly in multi-core environments, by minimizing the
software overhead associated with thread management.

Signed-off-by: Shell <smokewood@qq.com>
  • Loading branch information
polarvid committed May 17, 2024
1 parent 3d30b56 commit 2354e49
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 61 deletions.
4 changes: 3 additions & 1 deletion include/rtdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,8 +731,10 @@ struct rt_cpu
struct rt_thread *current_thread;

rt_uint8_t irq_switch_flag:1;
rt_uint8_t critical_switch_flag:1;
rt_uint8_t sched_lock_flag:1;
#ifndef ARCH_USING_HW_THREAD_SELF
rt_uint8_t critical_switch_flag:1;
#endif /* ARCH_USING_HW_THREAD_SELF */

rt_uint8_t current_priority;
rt_list_t priority_table[RT_THREAD_PRIORITY_MAX];
Expand Down
6 changes: 6 additions & 0 deletions include/rtsched.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ struct rt_sched_thread_ctx
rt_uint8_t sched_flag_locked:1; /**< calling thread have the scheduler locked */
rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */

#ifdef ARCH_USING_HW_THREAD_SELF
rt_uint8_t critical_switch_flag:1; /**< critical switch pending */
#endif /* ARCH_USING_HW_THREAD_SELF */

#ifdef RT_USING_SMP
rt_uint8_t bind_cpu; /**< thread is bind to cpu */
rt_uint8_t oncpu; /**< process on cpu */
Expand Down Expand Up @@ -138,6 +142,8 @@ rt_bool_t rt_sched_is_locked(void);

#define RT_SCHED_DEBUG_IS_LOCKED
#define RT_SCHED_DEBUG_IS_UNLOCKED

extern struct rt_thread *rt_current_thread;
#endif /* RT_USING_SMP */

/**
Expand Down
6 changes: 6 additions & 0 deletions libcpu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ if ARCH_ARMV8 && ARCH_CPU_64BIT
default y
config ARCH_USING_GENERIC_CPUID
bool "Using generic cpuid implemenation"
select ARCH_USING_HW_THREAD_SELF
default y if RT_USING_OFW
default n
endmenu
endif
Expand Down Expand Up @@ -270,3 +272,7 @@ config ARCH_HOST_SIMULATOR
config ARCH_CPU_STACK_GROWS_UPWARD
bool
default n

config ARCH_USING_HW_THREAD_SELF
bool
default n
24 changes: 19 additions & 5 deletions libcpu/aarch64/common/context_gcc.S
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* 2021-05-18 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for user thread
* 2024-01-06 Shell Fix barrier on irq_disable/enable
* 2024-01-18 Shell fix implicit dependency of cpuid management
*/

#ifndef __ASSEMBLY__
Expand All @@ -27,15 +28,28 @@ rt_thread_switch_interrupt_flag: .zero 8
#endif

.text
.weak rt_hw_cpu_id_set

.type rt_hw_cpu_id_set, @function
rt_hw_cpu_id_set:
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
#ifdef ARCH_USING_GENERIC_CPUID
.globl rt_hw_cpu_id_set
#else /* !ARCH_USING_GENERIC_CPUID */
.weak rt_hw_cpu_id_set
#endif /* ARCH_USING_GENERIC_CPUID */

#ifndef RT_USING_OFW
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
#ifdef ARCH_ARM_CORTEX_A55
lsr x0, x0, #8
lsr x0, x0, #8
#endif /* ARCH_ARM_CORTEX_A55 */
and x0, x0, #15
#endif /* !RT_USING_OFW */

#ifdef ARCH_USING_GENERIC_CPUID
msr tpidrro_el0, x0
#else
msr tpidr_el1, x0
#endif
and x0, x0, #15
msr tpidr_el1, x0
ret

/*
Expand Down
18 changes: 18 additions & 0 deletions libcpu/aarch64/common/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,24 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o

#endif /*RT_USING_SMP*/

/**
* Generic hw-cpu-id
*/
#ifdef ARCH_USING_GENERIC_CPUID

int rt_hw_cpu_id(void)
{
#if RT_CPUS_NR > 1
long cpuid;
__asm__ volatile("mrs %0, tpidrro_el0":"=r"(cpuid));
return cpuid;
#else
return 0;
#endif /* RT_CPUS_NR > 1 */
}

#endif /* ARCH_USING_GENERIC_CPUID */

/**
* @addtogroup ARM CPU
*/
Expand Down
42 changes: 17 additions & 25 deletions libcpu/aarch64/common/cpuport.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Date Author Notes
* 2023-10-25 Shell Move ffs to cpuport, add general implementation
* by inline assembly
* 2024-01-18 Shell support rt_hw_thread_self to improve overall performance
*/

#ifndef CPUPORT_H__
Expand All @@ -27,31 +28,6 @@ typedef struct
rt_uint32_t value;
} rt_hw_spinlock_t;

/**
* Generic hw-cpu-id
*/
#ifdef ARCH_USING_GENERIC_CPUID

#if RT_CPUS_NR > 1

rt_inline int rt_hw_cpu_id(void)
{
long cpuid;
__asm__ volatile("mrs %0, tpidr_el1":"=r"(cpuid));
return cpuid;
}

#else

rt_inline int rt_hw_cpu_id(void)
{
return 0;
}

#endif /* RT_CPUS_NR > 1 */

#endif /* ARCH_USING_GENERIC_CPUID */

#endif /* RT_USING_SMP */

#define rt_hw_barrier(cmd, ...) \
Expand Down Expand Up @@ -107,4 +83,20 @@ rt_inline int __rt_ffs(int value)

#endif /* RT_USING_CPU_FFS */

#ifdef ARCH_USING_HW_THREAD_SELF
rt_inline struct rt_thread *rt_hw_thread_self(void)
{
struct rt_thread *thread;
__asm__ volatile ("mrs %0, tpidr_el1":"=r"(thread));

return thread;
}

rt_inline void rt_hw_thread_set_self(struct rt_thread *thread)
{
__asm__ volatile ("msr tpidr_el1, %0"::"r"(thread));
}

#endif /* ARCH_USING_HW_THREAD_SELF */

#endif /*CPUPORT_H__*/
13 changes: 9 additions & 4 deletions libcpu/aarch64/cortex-a/entry_point.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* 2020-01-15 bigmagic the first version
* 2020-08-10 SummerGift support clang compiler
* 2023-04-29 GuEe-GUI support kernel's ARM64 boot header
* 2024-01-18 Shell fix implicit dependency of cpuid management
*/

#ifndef __ASSEMBLY__
Expand Down Expand Up @@ -94,7 +95,12 @@ _start:

/* Save cpu stack */
get_phy stack_top, .boot_cpu_stack_top

/* Save cpu id temp */
#ifdef ARCH_USING_HW_THREAD_SELF
msr tpidrro_el0, xzr
/* Save thread self */
#endif /* ARCH_USING_HW_THREAD_SELF */
msr tpidr_el1, xzr

bl init_cpu_el
Expand Down Expand Up @@ -149,11 +155,10 @@ _secondary_cpu_entry:

/* Get cpu id success */
sub x0, x2, #1
msr tpidr_el1, x0 /* Save cpu id global */
#else
bl rt_hw_cpu_id_set
mrs x0, tpidr_el1
#endif /* RT_USING_OFW */
/* Save cpu id global */
bl rt_hw_cpu_id_set
bl rt_hw_cpu_id

/* Set current cpu's stack top */
sub x0, x0, #1
Expand Down
Loading

0 comments on commit 2354e49

Please sign in to comment.