10. user.h(1/5)
冒頭の注釈
(注釈のまんま)
↓左端の数値は行番号 ・user構造体を定義している
・プロセスあたり1つ持つ
1 /* ・1プロセスあたりの全データであ
2 * The user structure. る
3 * One allocated per process. ・プロセスがスワップしている間は、
4 * Contains all per process data 参照しなくてよい
・ユーザのブロック長はUSIZE×64
5 * that doesn't need to be referenced
でこれはスタックポインタ用に使わ
6 * while the process is swapped. れる
7 * The user block is USIZE*64 bytes ・仮想カーネルのデータ長は
8 * long; resides at virtual kernel 140000 (ユーザ毎のシステムス
9 * loc 140000; contains the system タック含む)
10 * stack per user; is cross referenced・同じプロセスの中では、proc構造
と相互参照の関係にある
11 * with the proc structure for the
12 * same process.
13 */ 10
11. 14
15 #define EXCLOSE 01
user.h(2/5)
16
17 struct user
18 {
19 label_t u_rsav; /* save info when exchanging stacks */
20 int u_fper; /* FP error register */
退避時にスタックポインタを格納
21 int u_fpsaved; /* FP regs saved for this proc */
22 struct {
23 int u_fpsr; /* FP status register */
24 double u_fpregs[6]; /* FP registers */ ファイルI/O用の変数
25 } u_fps;
26 char u_segflg; /* IO flag: 0:user D; 1:system; 2:user I */ファイルI/Oの属性等
27 char u_error; /* return error code */ Dはデータ、I、は命令
28 short u_uid; /* effective user id */ systemはカーネルに相当
29 short u_gid; /* effective group id */
userはプロセスユーザと同義
30 short u_ruid; /* real user id */
31 short u_rgid; /* real group id */ proc構造体ポインタ
32 struct proc *u_procp; /* pointer to proc structure */
33 int *u_ap; /* pointer to arglist */ システムコールの引数リスト
34 union { /* syscall return values */
35 struct {
36 int r_val1; システムコールの戻り値
37 int r_val2; 例えばLinuxのコマンド
38 }; ls –laとかで得られる
39 off_t r_off;
一覧のデータを格納
40 time_t r_time; 11
41 } u_r; しておく
12. user.h(3/5)
42 caddr_t u_base; /* base address for IO */
プロセスユーザのI/Oの開始ア
43 unsigned int u_count; /* bytes remaining for IO */
44 off_t u_offset;
ドレス、オフセット、どこのディ
/* offset in file for IO */
45 struct inode *u_cdir; レクトリにあるか、パス名(この
/* pointer to inode of current directory */
46 struct inode *u_rdir; ころは物理アドレス空間を直
/* root directory of current process */
47 char u_dbuf[DIRSIZ]; 接扱っていた?)
/* current pathname component */
48 caddr_t u_dirp; /* pathname pointer */
49 struct direct u_dent; /* current directory entry */
50 struct inode *u_pdir; /* inode of parent directory of dirp */
51 int u_uisa[16]; /* prototype of segmentation addresses */
52 int u_uisd[16]; ファイルI/O
/* prototype of segmentation descriptors */
53 struct file *u_ofile[NOFILE]; /* pointers to file structures of open files *
(ちょっと詳細がわからない)
54 char u_pofile[NOFILE]; /* per-process flags of open files */
55 int u_arg[5]; /* arguments to current system call */
56 unsigned u_tsize; /* text size (clicks) */
57 unsigned u_dsize; /* data size (clicks) */ 現在のシステムコール戻り値
58 unsigned u_ssize; /* stack size (clicks) */
テキスト(プログラム)、データ
59 label_t u_qsav; /* label variable for quits and interrupts */
60 label_t u_ssav; /* label variable for swapping */
(固定値)、スタック(call時のP
61 int u_signal[NSIG]; /* disposition of signals */ C値の格納等)のサイズ、ス
62 time_t u_utime; /* this process user time */ ワップや退避時のラベル値
63 time_t u_stime; /* this process system time */
64 time_t u_cutime; /* sum of childs' utimes */ システムコールの戻り値
65 time_t u_cstime; /* sum of childs' stimes */ プロセスおよび子プロセスの
66 int *u_ar0; /* address of users saved R0 */ CPU使用時間など 12
13. user.h(4/5)
75 struct tty *u_ttyp; /* controlling ttytty(キャラクタ端末)制御用ポイ
pointer */
76 dev_t u_ttyd; /* controlling tty ンタとデバイス制御用情報
dev */
77 struct { /* header of executable file */
78 int ux_mag; /* magic number */
79 unsigned ux_tsize; /* text size */
80 unsigned ux_dsize; /* data size */ これはわからない…
81 unsigned ux_bsize; /* bss size */
82 unsigned ux_ssize; /* symbol table size */
実行するプログラムの
83 unsigned ux_entloc; /* entry location */ 情報(予備?)か何かか
84 unsigned ux_unused;
85 unsigned ux_relflg;
86 } u_exdata;
87 char u_comm[DIRSIZ];
88 time_t u_start;
89 char u_acflag;
90 short u_fpflag; /* unused now, will be later */ 予備用(互換性を取るため?)
91 short u_cmask; /* mask for file creation */
92 int u_stack[1];
93 /* kernel stack per user
94 * extends from u + USIZE*64
95 * backward not to reach here
96 */
97 };
98 13
16. 202 sched()
203 {
204 register struct proc *rp, *p;
sched(1/3)
205 register outage, inage; ところどころに出てくる、
206
207
int maxsize; 優先度を制御する関数。spl*の*が
208 /* 大きいほど優先度が高く、6が最高。
209 * find user to swap in;
210 * of users ready, select one out longest
他から割りこみが入って状態が
211 */ 変わらないようにしたい場合にこうする。
212
213 loop: ここでは最高優先度まで上げて以降の
214 spl6(); 操作を行っている
215 outage = -20000;
216 for (rp = &proc[0]; rp < &proc[NPROC]; rp++)
217 if (rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && プロセスの状態を総なめして
218 rp->p_time - (rp->p_nice-NZERO)*8 > outage) {
219 p = rp; ステータスが実行可能状態で
220 outage = rp->p_time - (rp->p_nice-NZERO)*8; 優先度が一番高いものを検出
221 }
222 /* (スワップイン候補を探す)
223 * If there is no one there, wait.
224 */
225 if (outage == -20000) {
226 runout++; 上記条件にあうプロセスが検出できなけれ
227 sleep((caddr_t)&runout, PSWP);
228 goto loop; ば、sleepを呼び出して待つ
229 }
230 spl0();
231
232 /* 優先度を最低に戻す
233 * See if there is core for that process;
234 * if so, swap it in.
235 */
236
237 if (swapin(p)) プロセスに割り当てられる資源(メモリなど)
238 goto loop; があればスワップインする 16
17. 240 /*
sched(2/3)
241 * none found.
242 * look around for core.
243 * Select the largest of those sleeping
244 * at bad priority; if none, select the oldest.
245 */
246
247 spl6();
248 p = NULL;
249 maxsize = -1;
250 inage = -1;
251 for (rp = &proc[0]; rp < &proc[NPROC]; rp++) {
252 if (rp->p_stat==SZOMB
253 || (rp->p_flag&(SSYS|SLOCK|SULOCK|SLOAD))!=SLOAD)
254 continue; CPUに割り当
255 if (rp->p_textp && rp->p_textp->x_flag&XLOCK)
256 continue; てる候補と資
257 if (rp->p_stat==SSLEEP&&rp->p_pri>=PZERO || rp->p_stat==SSTOP) { 源がない状
258 if (maxsize < rp->p_size) {
259 p = rp; 態。一番最初
260 maxsize = rp->p_size; にsleepしたプ
261 }
262 } else if (maxsize<0 && (rp->p_stat==SRUN||rp->p_stat==SSLEEP)) { ロセスを総な
263 if (rp->p_time+rp->p_nice-NZERO > inage) { めして検出す
264 p = rp;
265 inage = rp->p_time+rp->p_nice-NZERO; る(優先的に
266
267 }
}
スワップさせ
268 } るため)
269 spl0();
270 /* 17
18. sched(3/3)
270 /*
271 * Swap found user out if sleeping at bad pri,
272 * or if he has spent at least 2 seconds in core and
273 * the swapped-out process has spent at least 3 seconds out.
274 * Otherwise wait a bit and try again.
275 */
276 if (maxsize>=0 || (outage>=3 && inage>=2)) {
277 p->p_flag &= ~SLOAD;
CPUに割り当てられた時間
278 xswap(p, 1, 0); または、低い優先度でsleep
279 goto loop;
280 }
していたら、スワップを行う
281 spl6(); (理由がちょっと不明)
282 runin++;
283 sleep((caddr_t)&runin, PSWP);
284 goto loop;
285 }
286
18
19. 347 swtch()
348 {
349
350
352
register n;
register struct proc *p, *q, *pp, *pq;
/*
switch(1/2)
353 * If not the idle process, resume the idle process.
354 */
355 if (u.u_procp != &proc[0]) {
356 if (save(u.u_rsav)) {
357 sureg();
358 return;
359 } スタックポインタか?を保存
360 if (u.u_fpsaved==0) { や取り出している
361 savfp(&u.u_fps);
362 u.u_fpsaved = 1;
363 }
364 resume(proc[0].p_addr, u.u_qsav);
365 }
366 /*
367 * The first save returns nonzero when proc 0 is resumed
368 * by another process (above); then the second is not done
369 * and the process-search loop is entered.
370 *
371 * The first save returns 0 when swtch is called in proc 0
372 * from sched(). The second save returns 0 immediately, so
373 * in this case too the process-search loop is entered.
374 * Thus when proc 0 is awakened by being made runnable, it will
375 * find itself and resume itself at rsav, and return to sched().
376 */
377 if (save(u.u_qsav)==0 && save(u.u_rsav))
19
20. 379 loop:
380 spl6();
381 runrun = 0;
382
383
384
pp = NULL;
q = NULL;
n = 128;
switch(2/2)
385 /*
386 * Search for highest-priority runnable process
387 */
388 for(p=runq; p!=NULL; p=p->p_link) {
389 if((p->p_stat==SRUN) && (p->p_flag&SLOAD)) {
390 if(p->p_pri < n) {
391 pp = p;
392 pq = q;
393 n = p->p_pri;
394 }
395 }
396 q = p;
397 }
398 /*
399 * If no process is runnable, idle.
400 */
401 p = pp;
402 if(p == NULL) {
403 idle();
404 goto loop;
405 }
406 q = pq;
407 if(q == NULL)
408 runq = p->p_link;
409 else
410 q->p_link = p->p_link;
411 curpri = n;
412 spl0();
413 /*
414 * The rsav (ssav) contents are interpreted in the new address space
415 */
416 n = p->p_flag&SSWAP;
417 p->p_flag &= ~SSWAP;
418 resume(p->p_addr, n? u.u_ssav: u.u_rsav); 20
419 }