Linux-0.11カーネルソース分析シリーズ:プロセススケジューリング

1599 ワード

/*     
 *Author  : DavidLin     
 *Date    : 2014-12-10pm     
 *Email   : [email protected] or [email protected]     
 *world   : the city of SZ, in China     
 *Ver     : 000.000.001     
 *history :     editor      time            do     
 *          1)LinPeng       2014-12-10      created this file!     
 *          2)     
 */
/* author : linus */
void sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;
    
    if(!p)
        return;
    if(current == &(init_task.task))    //init      
        panic("task[0] trying to sleep");
    tmp = *p;   //tmp         
    *p  = current;    //         
    current->state = TASK_UNINTERRUPTIBLE;    //        
    schedule();    //    ,                 
    if(tmp)  //    next   
        tmp->state = 0;  //  next  
}

    sleep_on関数はsched.cファイルに見つかりました.これは小さな関数ですが、
次のような知識点が隠されているため、schedule()関数よりも理解が困難です.
1.ユーザースタックとカーネルスタックの違い;
2.カーネルスタックはどこで保存され、ユーザースタックと共有されますか?
3.いくつかのプロセスは同時に同じリソースのためにsleep_on、具体的な流れは?
4.sleepの後、どのように起こしますか?
5.異なるプロセスは同じsleepコードを使用し、異なるデータ、この概念の理解.
答え:以下は0.12カーネルに基づいて、2.6カーネルは異なりますが、基本的な概念は一致しています.
1.ユーザースタックはプロセスデータセグメントに保存され、カーネルスタックはプロセスpcbの物理ページに保存される.
fork.c 
p->tss.esp0 = PAGE_SIZE + (long)p;    //2.6     thread_info     
p->tss.ss0   = 0x10;    //             

2.共有しない理由は以上の通りである.
3.tmpは単一チェーンテーブルnextポインタに相当し、同じリソースを待つプロセスをリンクし、ヘッダポインタは常に最新の挿入プロセスを指す.
4.起動後にschedule()関数の後から実行し、カーネルで起動する.
6.コードセグメントは同じで、異なるメモリで実行できます.