今天在Linux 2.4源码sched.c中看到以下代码:
void sleep_on(wait_queue_head_t *q)
{
SLEEP_ON_VAR
current->state = TASK_UNINTERRUPTIBLE;
SLEEP_ON_HEAD
schedule();
SLEEP_ON_TAIL
}
sleep_on函数的主要作用是设置当前进程的状态为TASK_UNINTERRUPTIBLE,并将自己加入等待队列中。
我们知道记录进程状态的字段存在于进程描述符(task_struct)的state字段,那么current是如何得到当前进程的描述符地址的呢?如下:
static inline struct task_struct * get_current(void)
{
struct task_struct *current;
__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));
return current;
}
#define current get_current()
以上是i386架构下curent.h中的定义,从中我们可以看到
current = %esp & 0xffffe000,即进程描述符的地址等于进程内核栈的栈底地址与上 (~8191)。i386中内核栈与task_struct的关系如下图: