我了解到thread_info存储在堆栈的底部。 在查看内核的源代码时,我试图了解如何在linux内核中获取当前的thread_info? 下面的源代码是13比特屏蔽current_stack_pointer。
这是我无法得到的。 我不明白thread_info的位置会发生变化。 为什么它是当前的堆栈指针而不是堆栈的开始?
请帮我理解这段代码
/* * how to get the current stack pointer in C */ register unsigned long current_stack_pointer asm ("sp"); /* * how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) __attribute_const__; static inline struct thread_info *current_thread_info(void) { return (struct thread_info *) (current_stack_pointer & ~(THREAD_SIZE - 1)); }
答案 0 :(得分:0)
为什么它是当前的堆栈指针而不是堆栈的开始?
您始终可以从特定于平台的堆栈指针获取当前堆栈指针 注册,但你不能轻易找到堆栈的开头 - 它就不存在了。
为此,您可以限制线程堆栈在内存中的位置:堆栈始终在内存中按其大小保持对齐,其大小始终为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:当堆栈向下增长时,“当前堆栈的开始”是指最低地址。