code:swtch - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
- 进程调度主循环
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)
2186 /*
- 若静态变量p为空,则使其指向0#进程
2187 * Remember stack of caller
2188 */
2190 /*
- 保存当前函数的r5,r6
2191 * Switch to scheduler's stack
2192 */
2194
- 转入0#调度进程
2195 loop:
2196 runrun = 0;
2197 rp = p;
- 清runrun标志
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 p = &proc[0];
2208 if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) {
2209 if(rp->p_pri < n) {
2211 n = rp->p_pri;
2212 }
2213 }
2214 } while(--i);
2215 /*
- 遍历proc数组,寻找处于就绪状态,进程图像在内存中,且优先级最高的进程
2216 * If no process is runnable, idle.
2217 */
2218 if(p == NULL) {
2220 idle();
2221 goto loop;
2222 }
- 若没能搜到,进入闲置状态,等待中断
- 中断时若有进程醒来,则选中
2224 curpri = n;
2225 /* Switch to stack of the new process and set up
2226 * his segmentation registers.
2227 */
2229 sureg();
- 若搜到
- 则将当前优先级置为选中进程的优先级
- 将KISA6指向其ppda区首址
- 恢复被选中进程的r5,r6
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
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 p->p_flag =& ~SSWAP;
2243 }
- 若被选中进程带有SSWAP标志
- 则清SSWAP标志
- 调用aretu恢复r5,r6
2244 /* The value returned here has many subtle implications.
2245 * See the newproc comments.
2246 */
2247 return(1);
2248 }
- 该处的返回值1只有在新建子进程后,子进程从swtch中直接返回时才有用,参见进程调度之创建子进程
2249 /* -------------------------*/