Linux内核进程管理子系统有什么第六十三回 —— 进程主结构详解(59)
接前一篇文章:Linux内核进程管理子系统有什么第六十二回 —— 进程主结构详解(58)
本文内容参考:
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超
《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社
https://zhuanlan.zhihu.com/p/296750228
特此致谢!
进程管理核心结构 —— task_struct
12. current
前几回讲解了task_struct结构中的stack和thread_info,本回开始解析current。
实际上,current并不是struct task_struct的成员,而是一个宏定义。但是其与task_struct结构有着紧密的联系。内核中经常通过current宏来获得当前进程对应的struct task_sturct结构,其原理离不开进程内核栈,在介绍完了thread_info、task_sturct和内核栈的关系后,我们来看一下current宏的具体实现。
current的定义及实现是体系结构相关的,在Linux内核源码中搜索,会看到许多体系结构中都有其定义。
- x86架构
x86架构中,current宏的定义及实现代码在arch/x86/include/asm/current.h中,如下:
struct task_struct;DECLARE_PER_CPU(struct task_struct *, current_task);static __always_inline struct task_struct *get_current(void)
{return this_cpu_read_stable(current_task);
}#define current get_current()
在早期的内核版本(2.x、3.x)代码中,thread_info结构中还有指向struct task_sturct结构的指针成员。然而在x86体系结构中,Linux kernel一直采用的是另一种方式:使用current_task这个Per(每) CPU变量,来存储当前正在使用的cpu的进程描述符struct task_struct。
也就是说,新机制中,每个CPU运行的task_struct不再通过thread_info获取了,而是直接放在Per CPU变量里面了。
为了便于理解和回顾,这里再次贴出struct thread_info的定义,在arch/x86/include/asm/thread_info.h中,如下:
struct thread_info {unsigned long flags; /* low level flags */unsigned long syscall_work; /* SYSCALL_WORK_ flags */u32 status; /* thread synchronous flags */
#ifdef CONFIG_SMPu32 cpu; /* current CPU */
#endif
};
之所以这样做,是因为x86上通用寄存器有限,无法像ARM中那样单独拿出寄存器来存储进程描述符task_sturct结构的地址。同时,由于采用了每cpu变量current_task来保存当前运行进程的task_struct,所以在进程切换时,就需要更新该变量。
下一回解析ARM体系结构下current的定义和实现。