4

根据ARM 文档,线程 ID 寄存器像TPIDR_EL0or TPIDR_EL1

提供用于存储软件线程和进程 ID 的位置,以用于操作系统管理。这些寄存器对处理器行为没有影响。

为什么有人想将线程 ID 存储在一个特殊的寄存器中?ARM 处理器是否需要线程在内存中具有特殊的结构,就像 MMU 一样?线程对 ARM 来说是不是特别的东西,是 ARM 期望在某个地方找到的东西?或者我可以在不使用这个寄存器的情况下(有效地)实现线程吗?

我问是因为我在 Fuchsia OS 的 Zircon Kernel 上找到了这段代码:

static inline void arch_set_current_thread(Thread* t) {
  __arm_wsr64("tpidr_el1", (uint64_t)&t->arch_.thread_pointer_location);
  __isb(ARM_MB_SY);
}

在启动时它会创建一个线程并将其指针存储在tpidr_el1

4

1 回答 1

3

用户空间中与线程本地存储相关的所有内容都需要保存在每个线程的结构中。您需要将此结构的地址保存在某处。在 armv8 中,TPIDR_EL0可以用于此目的。在 x86_64 中,通常将fs段寄存器重新用于此用途。

Fuchsia 的线程本地存储 ABI记录在他们的网站上。

在紫红色中,TPIDR_EL0将为您提供pthread 结构。看看__allocate_thread这些内存是如何分配的。

一个使用示例(线程局部变量除外)是SafeStack 功能,它将第二个堆栈指针存储在 pthread 结构中。

对于内核,在 armv8TPIDR_EL1中,出于类似目的,用于保存内核线程结构的指针。

请注意,在 armv8 中,有一个用于EL0(用户空间)和EL1 (内核空间)的寄存器。在 x86-64 中,没有分离,处理起来有点尴尬:内核有一个内部位置来存储 gs 寄存器的“内核版本”,并使用swapgs指令在用户空间和内核空间 gs 寄存器之间进行切换。

于 2021-01-18T08:55:33.987 回答