本章讨论进程复制,继续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); /保存sp和r5,下一小节将重点讲解
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