日期:2014-05-16  浏览次数:20801 次

《linux 内核完全剖析》 exit.c 代码分析笔记

 

  exit.c 代码分析笔记

 release

          释放进程的函数release() 主要根据指定进程的任务数据结构指针,在任务数组中删除指定的进程指针,释放相关内存页,并立刻让内核重新调度进程的运行。



void release(struct task_struct * p) //释放p指向的进程
{
    int i;

    if (!p) //常规检测p是否为0
        return;
    if (p == current) { //不能把自己给释放了
        printk("task releasing itself\n\r");
        return;
    }
    for (i=1 ; i<NR_TASKS ; i++) //扫描所有的进程
        if (task[i]==p) { //找出p进程
            task[i]=NULL; //把p置空
            /* Update links */
            if (p->p_osptr) //调整链表
                p->p_osptr->p_ysptr = p->p_ysptr;
            if (p->p_ysptr)
                p->p_ysptr->p_osptr = p->p_osptr;
            else
                p->p_pptr->p_cptr = p->p_osptr;
            free_page((long)p); //释放p进程占用的内存页
            schedule();//任务调度
            return;
        }
    panic("trying to release non-existent task");
}

bad_task_ptr 和audit_ptree


#ifdef DEBUG_PROC_TREE //下面这部分代码是调试用的
/*
 * Check to see if a task_struct pointer is present in the task[] array
 * Return 0 if found, and 1 if not found.
 */
int bad_task_ptr(struct task_struct *p)
{
    int     i;

    if (!p)
        return 0;
    for (i=0 ; i<NR_TASKS ; i++)
        if (task[i] == p)
            return 0;
    return 1; //如果p不在task数组里面,那这个指针就有问题!
}
    
/*
 * This routine scans the pid tree and make sure the rep invarient still
 * holds.  Used for debugging only, since it's very slow....
 *
 * It looks a lot scarier than it really is.... we're doing ?nothing more
 * than verifying the doubly-linked list found?in p_ysptr and p_osptr,
 * and checking it corresponds with the process tree defined by p_cptr and
 * p_pptr;
 */
void audit_ptree() //其实不难,就是打印进程树的相关信息,方便调试用
{
    int    i;

    for (i=1 ; i<NR_TASKS ; i++) {
        if (!task[i])
            continue;
        if (bad_task_ptr(task[i]->p_pptr))
            printk("Warning, pid %d's parent link is bad\n",
                task[i]->pid);
        if (bad_task_ptr(task[i]->p_cptr))
            printk("Warning, pid %d's child link is bad\n",
                task[i]->pid);
        if (bad_task_ptr(task[i]->p_ysptr))
            printk("Warning, pid %d's ys link is bad\n",
                task[i]->pid);
        if (bad_task_ptr(task[i]->p_osptr))
            printk("Warning, pid %d's os link is bad\n",
                task[i]->pid);
        if (task[i]->p_pptr == task[i])
            printk("Warning, pid %d parent link points to self\n");
        if (task[i]->p_cptr == task[i])
            printk("Warning, pid %d child link points to self\n");
        if (task[i]->p_ysptr == task[i])
            printk("Warning, pid %d ys link points to self\n");
        if (task[i]->p_osptr == task[i])
            printk("Warning, pid %d os link points to self\n");
        if (task[i]->p_osptr) {
            if (task[i]->p_pptr != task[i]->p_osptr->p_pptr)
                printk(
            "Warning, pid %d older sibling %d parent is %d\n",
                task[i]->pid, task[i]->p_osptr->pid,
                task[i]->p_osptr->p_pptr->pid);
            if (task[i]->p_osptr->p_ysptr != task[i]