Skip to content

Commit 2354e49

Browse files
committed
[libcpu] arm64: Add hardware thread_self support
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 <[email protected]>
1 parent 3d30b56 commit 2354e49

File tree

9 files changed

+160
-61
lines changed

9 files changed

+160
-61
lines changed

include/rtdef.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,8 +731,10 @@ struct rt_cpu
731731
struct rt_thread *current_thread;
732732

733733
rt_uint8_t irq_switch_flag:1;
734-
rt_uint8_t critical_switch_flag:1;
735734
rt_uint8_t sched_lock_flag:1;
735+
#ifndef ARCH_USING_HW_THREAD_SELF
736+
rt_uint8_t critical_switch_flag:1;
737+
#endif /* ARCH_USING_HW_THREAD_SELF */
736738

737739
rt_uint8_t current_priority;
738740
rt_list_t priority_table[RT_THREAD_PRIORITY_MAX];

include/rtsched.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ struct rt_sched_thread_ctx
5656
rt_uint8_t sched_flag_locked:1; /**< calling thread have the scheduler locked */
5757
rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */
5858

59+
#ifdef ARCH_USING_HW_THREAD_SELF
60+
rt_uint8_t critical_switch_flag:1; /**< critical switch pending */
61+
#endif /* ARCH_USING_HW_THREAD_SELF */
62+
5963
#ifdef RT_USING_SMP
6064
rt_uint8_t bind_cpu; /**< thread is bind to cpu */
6165
rt_uint8_t oncpu; /**< process on cpu */
@@ -138,6 +142,8 @@ rt_bool_t rt_sched_is_locked(void);
138142

139143
#define RT_SCHED_DEBUG_IS_LOCKED
140144
#define RT_SCHED_DEBUG_IS_UNLOCKED
145+
146+
extern struct rt_thread *rt_current_thread;
141147
#endif /* RT_USING_SMP */
142148

143149
/**

libcpu/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ if ARCH_ARMV8 && ARCH_CPU_64BIT
1414
default y
1515
config ARCH_USING_GENERIC_CPUID
1616
bool "Using generic cpuid implemenation"
17+
select ARCH_USING_HW_THREAD_SELF
18+
default y if RT_USING_OFW
1719
default n
1820
endmenu
1921
endif
@@ -270,3 +272,7 @@ config ARCH_HOST_SIMULATOR
270272
config ARCH_CPU_STACK_GROWS_UPWARD
271273
bool
272274
default n
275+
276+
config ARCH_USING_HW_THREAD_SELF
277+
bool
278+
default n

libcpu/aarch64/common/context_gcc.S

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* 2021-05-18 Jesven the first version
99
* 2023-06-24 WangXiaoyao Support backtrace for user thread
1010
* 2024-01-06 Shell Fix barrier on irq_disable/enable
11+
* 2024-01-18 Shell fix implicit dependency of cpuid management
1112
*/
1213

1314
#ifndef __ASSEMBLY__
@@ -27,15 +28,28 @@ rt_thread_switch_interrupt_flag: .zero 8
2728
#endif
2829

2930
.text
30-
.weak rt_hw_cpu_id_set
31+
3132
.type rt_hw_cpu_id_set, @function
3233
rt_hw_cpu_id_set:
33-
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
34+
#ifdef ARCH_USING_GENERIC_CPUID
35+
.globl rt_hw_cpu_id_set
36+
#else /* !ARCH_USING_GENERIC_CPUID */
37+
.weak rt_hw_cpu_id_set
38+
#endif /* ARCH_USING_GENERIC_CPUID */
39+
40+
#ifndef RT_USING_OFW
41+
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
3442
#ifdef ARCH_ARM_CORTEX_A55
35-
lsr x0, x0, #8
43+
lsr x0, x0, #8
44+
#endif /* ARCH_ARM_CORTEX_A55 */
45+
and x0, x0, #15
46+
#endif /* !RT_USING_OFW */
47+
48+
#ifdef ARCH_USING_GENERIC_CPUID
49+
msr tpidrro_el0, x0
50+
#else
51+
msr tpidr_el1, x0
3652
#endif
37-
and x0, x0, #15
38-
msr tpidr_el1, x0
3953
ret
4054

4155
/*

libcpu/aarch64/common/cpu.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,24 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o
231231

232232
#endif /*RT_USING_SMP*/
233233

234+
/**
235+
* Generic hw-cpu-id
236+
*/
237+
#ifdef ARCH_USING_GENERIC_CPUID
238+
239+
int rt_hw_cpu_id(void)
240+
{
241+
#if RT_CPUS_NR > 1
242+
long cpuid;
243+
__asm__ volatile("mrs %0, tpidrro_el0":"=r"(cpuid));
244+
return cpuid;
245+
#else
246+
return 0;
247+
#endif /* RT_CPUS_NR > 1 */
248+
}
249+
250+
#endif /* ARCH_USING_GENERIC_CPUID */
251+
234252
/**
235253
* @addtogroup ARM CPU
236254
*/

libcpu/aarch64/common/cpuport.h

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Date Author Notes
88
* 2023-10-25 Shell Move ffs to cpuport, add general implementation
99
* by inline assembly
10+
* 2024-01-18 Shell support rt_hw_thread_self to improve overall performance
1011
*/
1112

1213
#ifndef CPUPORT_H__
@@ -27,31 +28,6 @@ typedef struct
2728
rt_uint32_t value;
2829
} rt_hw_spinlock_t;
2930

30-
/**
31-
* Generic hw-cpu-id
32-
*/
33-
#ifdef ARCH_USING_GENERIC_CPUID
34-
35-
#if RT_CPUS_NR > 1
36-
37-
rt_inline int rt_hw_cpu_id(void)
38-
{
39-
long cpuid;
40-
__asm__ volatile("mrs %0, tpidr_el1":"=r"(cpuid));
41-
return cpuid;
42-
}
43-
44-
#else
45-
46-
rt_inline int rt_hw_cpu_id(void)
47-
{
48-
return 0;
49-
}
50-
51-
#endif /* RT_CPUS_NR > 1 */
52-
53-
#endif /* ARCH_USING_GENERIC_CPUID */
54-
5531
#endif /* RT_USING_SMP */
5632

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

10884
#endif /* RT_USING_CPU_FFS */
10985

86+
#ifdef ARCH_USING_HW_THREAD_SELF
87+
rt_inline struct rt_thread *rt_hw_thread_self(void)
88+
{
89+
struct rt_thread *thread;
90+
__asm__ volatile ("mrs %0, tpidr_el1":"=r"(thread));
91+
92+
return thread;
93+
}
94+
95+
rt_inline void rt_hw_thread_set_self(struct rt_thread *thread)
96+
{
97+
__asm__ volatile ("msr tpidr_el1, %0"::"r"(thread));
98+
}
99+
100+
#endif /* ARCH_USING_HW_THREAD_SELF */
101+
110102
#endif /*CPUPORT_H__*/

libcpu/aarch64/cortex-a/entry_point.S

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* 2020-01-15 bigmagic the first version
88
* 2020-08-10 SummerGift support clang compiler
99
* 2023-04-29 GuEe-GUI support kernel's ARM64 boot header
10+
* 2024-01-18 Shell fix implicit dependency of cpuid management
1011
*/
1112

1213
#ifndef __ASSEMBLY__
@@ -94,7 +95,12 @@ _start:
9495

9596
/* Save cpu stack */
9697
get_phy stack_top, .boot_cpu_stack_top
98+
9799
/* Save cpu id temp */
100+
#ifdef ARCH_USING_HW_THREAD_SELF
101+
msr tpidrro_el0, xzr
102+
/* Save thread self */
103+
#endif /* ARCH_USING_HW_THREAD_SELF */
98104
msr tpidr_el1, xzr
99105

100106
bl init_cpu_el
@@ -149,11 +155,10 @@ _secondary_cpu_entry:
149155

150156
/* Get cpu id success */
151157
sub x0, x2, #1
152-
msr tpidr_el1, x0 /* Save cpu id global */
153-
#else
154-
bl rt_hw_cpu_id_set
155-
mrs x0, tpidr_el1
156158
#endif /* RT_USING_OFW */
159+
/* Save cpu id global */
160+
bl rt_hw_cpu_id_set
161+
bl rt_hw_cpu_id
157162

158163
/* Set current cpu's stack top */
159164
sub x0, x0, #1

0 commit comments

Comments
 (0)