曲径通幽论坛

标题: 进程描述符处理 | thread_info, thread_uion [打印本页]

作者: beyes    时间: 2011-2-27 22:27
标题: 进程描述符处理 | thread_info, thread_uion
平台:X86 32位
内核:2.6.24

对每个进程来说,Linux 将内核态的进程堆栈  和 线程描述符(thread_info) 紧凑地放在一个单独为进程分配的存储区域内。这个存储区域的大小一般为 8192 个字节,也就是 2 个页框大小。一般的,内核会让这 2 个页框占据的空间是连续的,而且第一个页框的起始地址是 2^13 的倍数。

thread_info 定义包含在 thread_union 联合体中(include/linux/sched.h):
union thread_union {
     struct thread_info thread_info;
     unsigned long stack[THREAD_SIZE/sizeof(long)];
};
通过 sizeof() 可以测试得 thread_info 结构的大小为 52 字节;而堆栈的大小 THREAD_SIZE/sizeof(long) = 2048 (存储 2048 个 4 字节大小的 long 型数据)。

下图则显示了在 2 页(8KB) 内存区中存放两种数据结构的方式(图片来自 ULK-3 ):

上图中,ESP 是堆栈寄存器。通过它容易获得当前在 CPU 上运行进程的 thread_info 结构的地址。获取的方法通过 current_thread_info() 函数来完成, current_thread_info() 定义在 include/asm-x86/thread_info_32.h 中:
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
     return (struct thread_info *)(current_stack_pointer & ~(THREAD_SIZE - 1));
}
上头 current_stack_pointer 就是堆栈指针 ESP,它是这样定义的:
/* how to get the current stack pointer from C */
register unsigned long current_stack_pointer asm("esp") __attribute_used__;

THREAD_SIZE 的值为 0x2000,这样 ~(THREAD_SIZE - 1) 为:0xE000,所以 current_stack_pointer & ~(THREAD_SIZE - 1) 的意思是将堆栈指针的 0-12 位屏蔽,从而得到了 thread_info 结构体的起始地址。在 thread_info 结构体中,它的第一个字段为 task (进程描述符) 指针,所以 current_thread_info()->task 即表示当前进程的进程描述符指针。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2