导读:
get_pid函数的意图很明显,就是找到一个pid分配给进程。首先变量last_pid,用于记录上一次分配给进程时的pid值。而分配的过程,一般而言是last_pid+1,如果超出进程个数的最大值(0x7fff),那么进程pid值从300开始重新查找未用的。也就是说,一般用户进程的pid值范围[300,7fff]。(0~299,留给系统)。对于变量next_safe的含义是,在[last_pid,next_safe]之间,都是没有使用过的pid,一旦last_pid+1大于了next_safe,也就是说pid值进入了不可靠空间,有可能这个值被使用,这时需要遍历task,来确认。这样遍历task,找到一个没有用过的pid,同时,确定next_safe,以保证next_safe到last_pid的区间中pid是空闲的,这样只要再次分配pid时,其值小于next_safe就可以直接得到,而不需要遍历task来查找空闲的pid。
static int get_pid(unsigned long flags)
{
static int next_safe = PID_MAX;//静态next_safe,初始时让它等于最大的pid值。
struct task_struct *p;
int pid;
if (flags &CLONE_PID)
return current->pid;
spin_lock(&lastpid_lock);
if((++last_pid) &0xffff8000) {//如果要分配的pid大于了8000,那么需要重300开始重新查找空闲的。
last_pid = 300; /* Skip daemons etc. */
goto inside;//显然,大于了8000,就不需要判断last_pid>=next_safe了。
}
if(last_pid >= next_safe) {//当准备分配的last_pid大于了next_safe,那么这个值就unsafe了。
inside:
next_safe = PID_MAX;//先把next_safe拉到最后,然后再一步一步的寻找最佳位置。
read_lock(&tasklist_lock);
repeat:
for_each_task(p) {
if(p->pid == last_pid ||
p->pgrp == last_pid ||
p->tgid == last_pid ||
p->session == last_pid) {
if(++last_pid >= next_safe) {
if(last_pid &0xffff8000)//next_safe值不总是PID_MAX
last_pid = 300;
next_safe = PID_MAX;
}
goto repeat;
}
if(p->pid >last_pid &&next_safe >p->pid)
next_safe = p->pid;
if(p->pgrp >last_pid &&next_safe >p->pgrp)
next_safe = p->pgrp;
if(p->session >last_pid &&next_safe >p->session)
next_safe = p->session;
//这是为了找到last_pid,到next_safe的最好空间。
}
read_unlock(&tasklist_lock);
}
pid = last_pid;
spin_unlock(&lastpid_lock);
return pid;
}
本文转自
http://felony.bokee.com/5558972.html
get_pid函数的意图很明显,就是找到一个pid分配给进程。首先变量last_pid,用于记录上一次分配给进程时的pid值。而分配的过程,一般而言是last_pid+1,如果超出进程个数的最大值(0x7fff),那么进程pid值从300开始重新查找未用的。也就是说,一般用户进程的pid值范围[300,7fff]。(0~299,留给系统)。对于变量next_safe的含义是,在[last_pid,next_safe]之间,都是没有使用过的pid,一旦last_pid+1大于了next_safe,也就是说pid值进入了不可靠空间,有可能这个值被使用,这时需要遍历task,来确认。这样遍历task,找到一个没有用过的pid,同时,确定next_safe,以保证next_safe到last_pid的区间中pid是空闲的,这样只要再次分配pid时,其值小于next_safe就可以直接得到,而不需要遍历task来查找空闲的pid。
static int get_pid(unsigned long flags)
{
static int next_safe = PID_MAX;//静态next_safe,初始时让它等于最大的pid值。
struct task_struct *p;
int pid;
if (flags &CLONE_PID)
return current->pid;
spin_lock(&lastpid_lock);
if((++last_pid) &0xffff8000) {//如果要分配的pid大于了8000,那么需要重300开始重新查找空闲的。
last_pid = 300; /* Skip daemons etc. */
goto inside;//显然,大于了8000,就不需要判断last_pid>=next_safe了。
}
if(last_pid >= next_safe) {//当准备分配的last_pid大于了next_safe,那么这个值就unsafe了。
inside:
next_safe = PID_MAX;//先把next_safe拉到最后,然后再一步一步的寻找最佳位置。
read_lock(&tasklist_lock);
repeat:
for_each_task(p) {
if(p->pid == last_pid ||
p->pgrp == last_pid ||
p->tgid == last_pid ||
p->session == last_pid) {
if(++last_pid >= next_safe) {
if(last_pid &0xffff8000)//next_safe值不总是PID_MAX
last_pid = 300;
next_safe = PID_MAX;
}
goto repeat;
}
if(p->pid >last_pid &&next_safe >p->pid)
next_safe = p->pid;
if(p->pgrp >last_pid &&next_safe >p->pgrp)
next_safe = p->pgrp;
if(p->session >last_pid &&next_safe >p->session)
next_safe = p->session;
//这是为了找到last_pid,到next_safe的最好空间。
}
read_unlock(&tasklist_lock);
}
pid = last_pid;
spin_unlock(&lastpid_lock);
return pid;
}
本文转自
http://felony.bokee.com/5558972.html