current宏进程描述符 从刚才看到的进程描述符和内核态堆栈之间的配对, 内核可以很容易的从esp寄存器的值获得当前在CPU 上运行的进程的描述符指针 因为这个内存区是8KB=213大小,内核必须做的就是 让esp有3位的有效位,以获得进程描述符的基地址 。这个工作由current?宏来完成 static inline struct task_struct get current(void) { struct task struct *current; asm_("andl %%esp,%0;":"=r"(current):"o"(~8191UL)); return current; 8191=8192-1=0x2000-1=0x1ff 取反:0xffe000(最后13位为0) #define current get_current()
xlanchen@2006.6.8 Embedded Operating Systems 11 current宏进程描述符 ⚫ 从刚才看到的进程描述符和内核态堆栈之间的配对, 内核可以很容易的从esp寄存器的值获得当前在CPU 上运行的进程的描述符指针 ⚫ 因为这个内存区是8KB=213大小,内核必须做的就是 让esp有13位的有效位,以获得进程描述符的基地址 ⚫ 这个工作由current宏来完成 8191=8192-1=0x2000-1=0x1fff 取反:0xffffe000(最后13位为0)
Current?宏的使用 ●Current2宏可以看成当前进程的进程描述符指 针在内核中直接使用 。比如current->pid返回在CPU上正在执行的进程的 PID if (pid &pid current->pid) xlanchen@2006.6.8 Embedded Operating Systems 12
xlanchen@2006.6.8 Embedded Operating Systems 12 Current宏的使用 ⚫ Current宏可以看成当前进程的进程描述符指 针在内核中直接使用 ⚫ 比如current->pid返回在CPU上正在执行的进程的 PID
进程链表 ·为了对给定类型的进程(比如所有在可运行状 态下的进程)进行有效的搜索,内核维护了几 个进程链表 ·所有进程链表 Figure 3-3.The process list prev_task next_task prev_task next_task prev_task next_task init task 在进程描述符中:struct task_struct*next_task,*prev_task; xlanchen@2006.6.8 13
xlanchen@2006.6.8 Embedded Operating Systems 13 进程链表 ⚫ 为了对给定类型的进程(比如所有在可运行状 态下的进程)进行有效的搜索,内核维护了几 个进程链表 ⚫ 所有进程链表 在进程描述符中:
●SET LINKS和REMOVE LINKS宏用来分别在 进程链表中插入和删除一个进程描述符。 #define SET_LINKS(p)do{ (p)->next_task =&init_task; (p)->prev_task init_task.prev task; init task.prev_task->next_task (p); init task.prev_task =(p);\ (p)->p_ysptr NULL;\ if (((p)->p_osptr =(p)->p_pptr->p_cptr)!=NULL)\ (p)->p_osptr->p_ysptr p;\ (p)->p_pptr->p_cptr p;\ while (0) xiancnen(@∠Uub.b.6 Empeaaea uperating Systems 14
xlanchen@2006.6.8 Embedded Operating Systems 14 ⚫ SET_LINKS和REMOVE_LINKS宏用来分别在 进程链表中插入和删除一个进程描述符
。for each task宏扫描整个进程链表 #define for_each_task(p)\ for (p &init_task (p p->next_task)!=&init_task ; xlanchen@2006.6.8 Embedded Operating Systems 15
xlanchen@2006.6.8 Embedded Operating Systems 15 ⚫ for_each_task宏扫描整个进程链表