(莱昂氏unix源代码分析导读-11)系统初启(4)

 

本章讨论进程复制,继续Main函数。

 

1625 */

1626

1627 if(newproc()) {                        

……

 

现在看newproc的代码。

1826 newproc()

1827 {

          ......

1840 retry:

1841     mpid++;                                                                              /生成进程Id

1842     if(mpid < 0) {

1843             mpid = 0;

1844             goto retry;

1845     }

1846     for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) {     /这个for循环有两重意思

1847             if(rpp->p_stat == NULL & && p==NULL)       

1848                           p = rpp;                                                       /1)在进程描述表内选取一个空表项;

1849                          if (rpp->p_pid==mpid)                                /2)检查刚生成的进程Id是否为唯一

1850                                                 goto retry;

1851      }

1852      if ((rpp = p)==NULL)                                                      /进程表满,Error

1853                 panic("no procs");

1854

1855      /*

1856       * make proc entry for new proc

1857       */

1858                                                            /rpp为新挑选的空表项

1859      rip = u.u_procp;                           /rip为当前process(即#0进程)的进程表项

1860      up = rip;                                   

1861      rpp->p_stat = SRUN;                  /开始设置新表项的信息     

1862      rpp->p_flag = SLOAD;

1863      rpp->p_uid = rip->p_uid;            /很多信息都与当前进程的设置一样

1864      rpp->p_ttyp = rip->p_ttyp;

1865      rpp->p_nice = rip->p_nice;

1866      rpp->p_textp = rip->p_textp;

1867      rpp->p_pid = mpid;                         /进程Id

1868      rpp->p_ppid = rip->p_pid;            /新进程的父进程为当前进程(#0进程)

1869      rpp->p_time = 0;

1870

1871     /*

1872      * make duplicate entries

1873      * where needed

1874     */

1875

1876     for(rip = &u.u_ofile[0]; rip < &u.u_ofile[NOFILE];)   /--

1877           if((rpp = *rip++) != NULL)

1878                   rpp->f_count++;

1879     if((rpp=up->p_textp) != NULL) {                                 /参见莱昂注释

1880           rpp->x_count++;

1881           rpp->x_ccount++;

1882     }

1883     u.u_cdir->i_count++;                                                       --/

1884     /*

1885      * Partially simulate the environment

1886      * of the new process so that when it is actually

1887      * created (by copying) it will look right.

1888      */

1889      savu(u.u_rsav);                             /保存spr5,下一小节将重点讲解

1890      rpp = p;

1891      u.u_procp = rpp;                           /暂时更改u_procp,使其指向新进程表项

1892      rip = up;                                        /rip指向#0进程

1893      n = rip->p_size;

1894      a1 = rip->p_addr;

1895      rpp->p_size = n;                           /设置新进程的“私有空间”长度(单位:block

1896      a2 = malloc(coremap, n);               /为新进程分配“私有空间”

1897      /*

1898       * If there is not enough core for the

1899       * new process, swap put the current process to

1900       * generate the copy.

1901       */

1902       if(a2 == NULL) {                           /--

1903             rip->p_stat = SIDL;                  /    

1904             rpp->p_addr = a1;                     /空间不够系统初启时,不会发生这种情况,

1905             savu(u.u_ssav);                          /故先跳过

1906             xswap(rpp, 0, 0);

1907             rpp->p_flag =| SSWAP;

1908             rip->p_stat = SRUN;                 --/

1909       } else {

1910       /*

1911        * There is core, so just copy.

1912        */

1913             rpp->p_addr = a2;                 /设置新进程的“私有空间”地址——新进程诞生了!

1914             while(n--)                              /复制#0的私有空间的内容,赋给新进程

1915                  copyseg(a1++, a2++);     / copyseg是我们的老朋友了

1916      }                                   

1917      u.u_procp = rip;                          /恢复u_procp,使其指向#0进程

1918      return(0);                                     /返回值为0

1919 }

 

看来,newproc()函数并没有执行什么神奇魔法,它生成了一个与#0几乎一模一样的新进程。

但是,cpu仍在#0手中,新进程尚未得到执行。

 

回到main函数:

1627 if(newproc()) {                              /返回值为0,故此if语句内都不会被执行

1628      expand(USIZE+1);                   

1629      estabur(0, 1, 0, 0);   

1630      copyout(icode, 0, sizeof icode);

1631      /*

1632           * Return goes to loc. 0 of user init

1633           * code just copied out.

1634      */

1635      return;

1636 }

1637  sched();                                     /执行sched,下小节讨论   

1638 }

 

接下来的几小节是本章的高潮部分,请稍候。

 

博客地址:http://blog.csdn.net/cszhao1980

 博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

你可能感兴趣的:(unix,user,null,UP,代码分析)