【问题标题】:current_thread_info() inline function in Linux kernel?Linux内核中的current_thread_info()内联函数?
【发布时间】:2017-08-27 20:09:18
【问题描述】:

我了解到 thread_info 存储在堆栈的底部。 在查看内核源代码时,我试图了解如何在 linux 内核中获取当前的 thread_info?
下面的源码是current_stack_pointer的13bits masking。

这是我无法得到的。 我不明白 thread_info 的位置发生了变化。 为什么是当前栈指针而不是栈的开始?

请帮助我理解这段代码

/* * 如何在 C 中获取当前堆栈指针 */ 注册 unsigned long current_stack_pointer asm ("sp"); /* * 如何从 C 中获取线程信息结构体 */ 静态内联结构 thread_info *current_thread_info(void) __attribute_const__; 静态内联结构 thread_info *current_thread_info(void) { 返回(结构线程信息*) (current_stack_pointer & ~(THREAD_SIZE - 1)); }

【问题讨论】:

  • 您使用的是什么架构?查找当前任务信息是依赖于架构的。这就是为什么有include/asm/current.h#define current。在 x86 上,我们有 #define current get_current(),但在 IBM s390 上,我们有 #define current ((struct task_struct *const)S390_lowcore.current_task)。所以,要小心地复制堆栈指针。
  • 感谢您的评论。我正在使用 ARM 架构。 arch/arm/include/asm/thread_info.h

标签: c linux multithreading stack kernel


【解决方案1】:

为什么是当前栈指针而不是栈首?

您始终可以从平台特定的堆栈指针获取当前堆栈指针 注册,但你不能轻易找到堆栈的开始 - 它不在那里。

为此,您可以限制线程堆栈在内存中的位置:堆栈在内存中始终按其大小保持对齐,并且其大小始终是 2 的幂。这样,如果堆栈大小为 2^n,则将较低的 n 归零会为您提供堆栈的开始。

在现代 Linux 堆栈中通常为 8 KiB,并且始终以 8 KiB 对齐(其地址的低 13 位始终为 0)。将当前堆栈指针的低 13 位清零即可开始堆栈。

这正是表达式current_stack_pointer & ~(THREAD_SIZE - 1) 所做的:查找当前堆栈的开始。这并不意味着struct thread_info 会在内存中移动——它不会。即使堆栈指针发生变化,将低位清零也会在线程中为您提供相同的值。这就是为什么它也被标记为__attribute_const__,它扩展为__attribute__((const)),并告诉GCC这个函数总是返回相同的值,因此可以省略对该函数的多次调用。


PS:随着堆栈向下增长,“当前堆栈的开始”是指最低地址。

【讨论】:

    猜你喜欢
    • 2012-07-21
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多