1800: # 1801: /* 1802: */ 1803: 1804: #include "../param.h" 1805: #include "../user.h" 1806: #include "../proc.h" 1807: #include "../text.h" 1808: #include "../systm.h" 1809: #include "../file.h" 1810: #include "../inode.h" 1811: #include "../buf.h" 1812: /* --------------------------- */ 1813: /* 1814: * Create a new process-- the internal version of 1815: * sys fork. 1816: * It returns 1 in the new process. 1817: * How this happens is rather hard to understand. 1818: * The essential fact is that the new process is created 1819: * in such a way that appears to have started executing 1820: * in the same call to newproc as the parent; 1821: * but in fact the code that runs is that of swtch. 1822: * The subtle implication of the returned value of swtch 1823: * (see above) is that this is the value that newproc's 1824: * caller in the new process sees. 1825: */ 1826: newproc() 1827: { 1828: int a1, a2; 1829: struct proc *p, *up; 1830: register struct proc *rpp; 1831: register *rip, n; 1832: 1833: p = NULL; 1834: /* 1835: * First, just locate a slot for a process 1836: * and copy the useful info from this process into it. 1837: * The panic "cannot happen" because fork has already 1838: * checked for the existence of a slot. 1839: */ 1840: retry: 1841: mpid++; 1842: if(mpid < 0) { 1843: mpid = 0; 1844: goto retry; 1845: } 1846: for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) { 1847: if(rpp->p_stat == NULL && p==NULL) 1848: p = rpp; 1849: if (rpp->p_pid==mpid) 1850: goto retry; 1851: } 1852: if ((rpp = p)==NULL) 1853: panic("no procs"); 1854: 1855: /* 1856: * make proc entry for new proc 1857: */ 1858: 1859: rip = u.u_procp; 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; 1868: rpp->p_ppid = rip->p_pid; 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); 1890: rpp = p; 1891: u.u_procp = rpp; 1892: rip = up; 1893: n = rip->p_size; 1894: a1 = rip->p_addr; 1895: rpp->p_size = n; 1896: a2 = malloc(coremap, n); 1897: /* 1898: * If there is not enough core for the 1899: * new process, swap out the current process to generate the 1900: * 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--) 1915: copyseg(a1++, a2++); 1916: } 1917: u.u_procp = rip; 1918: return(0); 1919: } 1920: /* --------------------------- */ 1921: 1922: /* 1923: * The main loop of the scheduling (swapping) 1924: * process. 1925: * The basic idea is: 1926: * see if anyone wants to be swapped in; 1927: * swap out processes until there is room; 1928: * swap him in; 1929: * repeat. 1930: * Although it is not remarkably evident, the basic 1931: * synchronization here is on the runin flag, which is 1932: * slept on and is set once per second by the clock routine. 1933: * Core shuffling therefore takes place once per second. 1934: * 1935: * panic: swap error -- IO error while swapping. 1936: * this is the one panic that should be 1937: * handled in a less drastic way. Its 1938: * very hard. 1939: */ 1940: sched() 1941: { 1942: struct proc *p1; 1943: register struct proc *rp; 1944: register a, n; 1945: 1946: /* 1947: * find user to swap in 1948: * of users ready, select one out longest 1949: */ 1950: 1951: goto loop; 1952: 1953: sloop: 1954: runin++; 1955: sleep(&runin, PSWP); 1956: 1957: loop: 1958: spl6(); 1959: n = -1; 1960: for(rp = &proc[0]; rp < &proc[NPROC]; rp++) 1961: if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && 1962: rp->p_time > n) { 1963: p1 = rp; 1964: n = rp->p_time; 1965: } 1966: if(n == -1) { 1967: runout++; 1968: sleep(&runout, PSWP); 1969: goto loop; 1970: } 1971: 1972: /* 1973: * see if there is core for that process 1974: */ 1975: 1976: spl0(); 1977: rp = p1; 1978: a = rp->p_size; 1979: if((rp=rp->p_textp) != NULL) 1980: if(rp->x_ccount == 0) 1981: a =+ rp->x_size; 1982: if((a=malloc(coremap, a)) != NULL) 1983: goto found2; 1984: 1985: /* 1986: * none found, 1987: * look around for easy core 1988: */ 1989: 1990: spl6(); 1991: for(rp = &proc[0]; rp < &proc[NPROC]; rp++) 1992: if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && 1993: (rp->p_stat == SWAIT || rp->p_stat==SSTOP)) 1994: goto found1; 1995: 1996: /* 1997: * no easy core, 1998: * if this process is deserving, 1999: * look around for 2000: * oldest process in core 2001: */ 2002: 2003: if(n < 3) 2004: goto sloop; 2005: n = -1; 2006: for(rp = &proc[0]; rp < &proc[NPROC]; rp++) 2007: if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && 2008: (rp->p_stat==SRUN || rp->p_stat==SSLEEP) && 2009: rp->p_time > n) { 2010: p1 = rp; 2011: n = rp->p_time; 2012: } 2013: if(n < 2) 2014: goto sloop; 2015: rp = p1; 2016: 2017: /* 2018: * swap user out 2019: */ 2020: 2021: found1: 2022: spl0(); 2023: rp->p_flag =& ~SLOAD; 2024: xswap(rp, 1, 0); 2025: goto loop; 2026: 2027: /* 2028: * swap user in 2029: */ 2030: 2031: found2: 2032: if((rp=p1->p_textp) != NULL) { 2033: if(rp->x_ccount == 0) { 2034: if(swap(rp->x_daddr, a, rp->x_size, B_READ)) 2035: goto swaper; 2036: rp->x_caddr = a; 2037: a =+ rp->x_size; 2038: } 2039: rp->x_ccount++; 2040: } 2041: rp = p1; 2042: if(swap(rp->p_addr, a, rp->p_size, B_READ)) 2043: goto swaper; 2044: mfree(swapmap, (rp->p_size+7)/8, rp->p_addr); 2045: rp->p_addr = a; 2046: rp->p_flag =| SLOAD; 2047: rp->p_time = 0; 2048: goto loop; 2049: 2050: swaper: 2051: panic("swap error"); 2052: } 2053: /* --------------------------- */ 2054: 2055: /* 2056: * Give up the processor till a wakeup occurs 2057: * on chan, at which time the process 2058: * enters the scheduling queue at priority pri. 2059: * The most important effect of pri is that when 2060: * pri<0 a signal cannot disturb the sleep; 2061: * if pri>=0 signals will be processed. 2062: * Callers of this routine must be prepared for 2063: * premature return, and check that the reason for 2064: * sleeping has gone away. 2065: */ 2066: sleep(chan, pri) 2067: { 2068: register *rp, s; 2069: 2070: s = PS->integ; 2071: rp = u.u_procp; 2072: if(pri >= 0) { 2073: if(issig()) 2074: goto psig; 2075: spl6(); 2076: rp->p_wchan = chan; 2077: rp->p_stat = SWAIT; 2078: rp->p_pri = pri; 2079: spl0(); 2080: if(runin != 0) { 2081: runin = 0; 2082: wakeup(&runin); 2083: } 2084: swtch(); 2085: if(issig()) 2086: goto psig; 2087: } else { 2088: spl6(); 2089: rp->p_wchan = chan; 2090: rp->p_stat = SSLEEP; 2091: rp->p_pri = pri; 2092: spl0(); 2093: swtch(); 2094: } 2095: PS->integ = s; 2096: return; 2097: 2098: /* 2099: * If priority was low (>=0) and 2100: * there has been a signal, 2101: * execute non-local goto to 2102: * the qsav location. 2103: * (see trap1/trap.c) 2104: */ 2105: psig: 2106: aretu(u.u_qsav); 2107: } 2108: /* --------------------------- */ 2109: 2110: /* 2111: * Wake up all processes sleeping on chan. 2112: */ 2113: wakeup(chan) 2114: { 2115: register struct proc *p; 2116: register c, i; 2117: 2118: c = chan; 2119: p = &proc[0]; 2120: i = NPROC; 2121: do { 2122: if(p->p_wchan == c) { 2123: setrun(p); 2124: } 2125: p++; 2126: } while(--i); 2127: } 2128: /* --------------------------- */ 2129: 2130: /* 2131: * Set the process running; 2132: * arrange for it to be swapped in if necessary. 2133: */ 2134: setrun(p) 2135: { 2136: register struct proc *rp; 2137: 2138: rp = p; 2139: rp->p_wchan = 0; 2140: rp->p_stat = SRUN; 2141: if(rp->p_pri < curpri) 2142: runrun++; 2143: if(runout != 0 && (rp->p_flag&SLOAD) == 0) { 2144: runout = 0; 2145: wakeup(&runout); 2146: } 2147: } 2148: /* --------------------------- */ 2149: 2150: /* 2151: * Set user priority. 2152: * The rescheduling flag (runrun) 2153: * is set if the priority is higher 2154: * than the currently running process. 2155: */ 2156: setpri(up) 2157: { 2158: register *pp, p; 2159: 2160: pp = up; 2161: p = (pp->p_cpu & 0377)/16; 2162: p =+ PUSER + pp->p_nice; 2163: if(p > 127) 2164: p = 127; 2165: if(p > curpri) 2166: runrun++; 2167: pp->p_pri = p; 2168: } 2169: /* --------------------------- */ 2170: 2171: 2172: /* 2173: * This routine is called to reschedule the CPU. 2174: * if the calling process is not in RUN state, 2175: * arrangements for it to restart must have 2176: * been made elsewhere, usually by calling via sleep. 2177: */ 2178: swtch() 2179: { 2180: static struct proc *p; 2181: register i, n; 2182: register struct proc *rp; 2183: 2184: if(p == NULL) 2185: p = &proc[0]; 2186: /* 2187: * Remember stack of caller 2188: */ 2189: savu(u.u_rsav); 2190: /* 2191: * Switch to scheduler's stack 2192: */ 2193: retu(proc[0].p_addr); 2194: 2195: loop: 2196: runrun = 0; 2197: rp = p; 2198: p = NULL; 2199: n = 128; 2200: /* 2201: * Search for highest-priority runnable process 2202: */ 2203: i = NPROC; 2204: do { 2205: rp++; 2206: if(rp >= &proc[NPROC]) 2207: rp = &proc[0]; 2208: if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) { 2209: if(rp->p_pri < n) { 2210: p = rp; 2211: n = rp->p_pri; 2212: } 2213: } 2214: } while(--i); 2215: /* 2216: * If no process is runnable, idle. 2217: */ 2218: if(p == NULL) { 2219: p = rp; 2220: idle(); 2221: goto loop; 2222: } 2223: rp = p; 2224: curpri = n; 2225: /* Switch to stack of the new process and set up 2226: * his segmentation registers. 2227: */ 2228: retu(rp->p_addr); 2229: sureg(); 2230: /* 2231: * If the new process paused because it was 2232: * swapped out, set the stack level to the last call 2233: * to savu(u_ssav). This means that the return 2234: * which is executed immediately after the call to aretu 2235: * actually returns from the last routine which did 2236: * the savu. 2237: * 2238: * You are not expected to understand this. 2239: */ 2240: if(rp->p_flag&SSWAP) { 2241: rp->p_flag =& ~SSWAP; 2242: aretu(u.u_ssav); 2243: } 2244: /* The value returned here has many subtle implications. 2245: * See the newproc comments. 2246: */ 2247: return(1); 2248: } 2249: /* --------------------------- */ 2250: 2251: /* 2252: * Change the size of the data+stack regions of the process. 2253: * If the size is shrinking, it's easy-- just release the extra core. 2254: * If it's growing, and there is core, just allocate it 2255: * and copy the image, taking care to reset registers to account 2256: * for the fact that the system's stack has moved. 2257: * 2258: * If there is no core, arrange for the process to be swapped 2259: * out after adjusting the size requirement-- when it comes 2260: * in, enough core will be allocated. 2261: * Because of the ssave and SSWAP flags, control will 2262: * resume after the swap in swtch, which executes the return 2263: * from this stack level. 2264: * 2265: * After the expansion, the caller will take care of copying 2266: * the user's stack towards or away from the data area. 2267: */ 2268: expand(newsize) 2269: { 2270: int i, n; 2271: register *p, a1, a2; 2272: 2273: p = u.u_procp; 2274: n = p->p_size; 2275: p->p_size = newsize; 2276: a1 = p->p_addr; 2277: if(n >= newsize) { 2278: mfree(coremap, n-newsize, a1+newsize); 2279: return; 2280: } 2281: savu(u.u_rsav); 2282: a2 = malloc(coremap, newsize); 2283: if(a2 == NULL) { 2284: savu(u.u_ssav); 2285: xswap(p, 1, n); 2286: p->p_flag =| SSWAP; 2287: swtch(); 2288: /* no return */ 2289: } 2290: p->p_addr = a2; 2291: for(i=0; i<n; i++) 2292: copyseg(a1+i, a2++); 2293: mfree(coremap, n, a1); 2294: retu(p->p_addr); 2295: sureg(); 2296: } 2297: /* --------------------------- */