0x9*_*x90 15 c kernel arm linux-kernel
有人可以解释一下这里从linux内核获取的这段代码吗?
/*
* 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)
{
register unsigned long sp asm ("sp");
return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
}
Run Code Online (Sandbox Code Playgroud)
问题:
__attribute_const__?register unsigned long sp asm ("sp");(struct thread_info *)(sp & ~(THREAD_SIZE - 1));返回指向结构的指针?jpa*_*jpa 14
属性const意味着返回的指针在程序的持续时间内保持不变.实际上,只有在一个线程的范围内才是这样,但我无法想到编译器甚至会尝试优化线程之间的访问的任何情况.
使用register并将asm("sp")变量绑定到调用的硬件寄存器sp,即当前堆栈指针.这样,代码不必用汇编语言编写就可以直接访问该寄存器.
THREAD_SIZE是一个常量,它给出了为线程堆栈分配的内存量.我假设它总是必须是2的幂,例如8千字节可能是典型的值.
然后表达式~(THREAD_SIZE - 1)给出一个位掩码,用于删除实际的堆栈地址.对于8 kB堆栈,它将是0xffffe000.
通过按位并使用堆栈指针值,我们得到为堆栈分配的最低地址.在此体系结构中,线程信息存储在那里.这只是一个设计决策,他们可以使用其他一些地方来存储信息.
堆栈指针对于获取线程信息很有用,因为每个线程总是有自己的堆栈.
Linux中的内核堆栈具有固定大小(THREAD_SIZE- 2页,或x86上的8KB).在struct thread_info一个线程保持在堆栈的内存块的底部.请记住堆栈向下工作,因此堆栈指针最初指向内存块的末尾,当数据被推入堆栈时,堆栈指针向内存块的底部移动.当然,其他CPU架构可能使用其他技术.
因此,如果您获取当前堆栈指针值,并屏蔽低位位,struct thread_info则使用当前堆栈获取指向线程的指针.
这条线:
register unsigned long sp asm ("sp");
Run Code Online (Sandbox Code Playgroud)
告诉GCC将变量映射sp到CPU寄存器sp(我觉得这里使用的是16位寄存器名称 - 这是来自实际的Linux源代码树吗?).
__attribute_const__通常被定义为__attribute__((__const__))当GCC是编译器时(对于Linux内核来说它是否还有其他什么?).这告诉GCC该函数没有副作用 - 实际上它比它强一点:函数只使用参数并仅返回基于那些参数的值.这可能为编译器提供了一些优化机会 - 它可以假设没有更改全局变量,甚至没有读取(因此编译器可以自由推迟更新内存,它可能需要为"正常"函数调用进行更新).
| 归档时间: |
|
| 查看次数: |
4560 次 |
| 最近记录: |