曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5689|回复: 0
打印 上一主题 下一主题

进程描述符处理 | thread_info, thread_uion

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2011-2-27 22:27:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
平台: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 即表示当前进程的进程描述符指针。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 01:50 , Processed in 0.061960 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表