16
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6 <!DOCTYPE html>
|
|
7 <html>
|
|
8 <head>
|
|
9 <meta http-equiv="content-type" content="text/html;charset=utf-8">
|
|
10 <title>継続を用いたxv6 kernelの書き換え</title>
|
|
11
|
|
12 <meta name="generator" content="Slide Show (S9) v4.0.1 on Ruby 2.3.7 (2018-03-28) [universal.x86_64-darwin17]">
|
|
13 <meta name="author" content="Takahiro Sakamoto, Yu Tobaru, Shinji Kono" >
|
|
14
|
|
15 <!-- style sheet links -->
|
|
16 <link rel="stylesheet" href="s6/themes/screen.css" media="screen">
|
|
17 <link rel="stylesheet" href="s6/themes/print.css" media="print">
|
|
18 <link rel="stylesheet" href="s6/themes/blank.css" media="screen,projection">
|
|
19
|
|
20 <!-- JS -->
|
|
21 <script src="s6/js/jquery-1.11.3.min.js"></script>
|
|
22 <script src="s6/js/jquery.slideshow.js"></script>
|
|
23 <script src="s6/js/jquery.slideshow.counter.js"></script>
|
|
24 <script src="s6/js/jquery.slideshow.controls.js"></script>
|
|
25 <script src="s6/js/jquery.slideshow.footer.js"></script>
|
|
26 <script src="s6/js/jquery.slideshow.autoplay.js"></script>
|
|
27
|
|
28 <!-- prettify -->
|
|
29 <link rel="stylesheet" href="scripts/prettify.css">
|
|
30 <script src="scripts/prettify.js"></script>
|
|
31
|
|
32 <style>
|
|
33 .slide {page-break-after: always;}
|
|
34 </style>
|
|
35
|
|
36
|
|
37
|
|
38
|
|
39 </head>
|
|
40 <body>
|
|
41
|
|
42 <div class="layout">
|
|
43 <div id="header"></div>
|
|
44 <div id="footer">
|
|
45 <div align="right">
|
|
46 <img src="s6/images/logo.svg" width="200px">
|
|
47 </div>
|
|
48 </div>
|
|
49 </div>
|
|
50
|
|
51 <div class="presentation">
|
|
52
|
|
53 <div class='slide cover'>
|
|
54 <table width="90%" height="90%" border="0" align="center">
|
|
55 <tr>
|
|
56 <td>
|
|
57 <div align="center">
|
|
58 <h1><font color="#808db5">継続を用いたxv6 kernelの書き換え</font></h1>
|
|
59 </div>
|
|
60 </td>
|
|
61 </tr>
|
|
62 <tr>
|
|
63 <td>
|
|
64 <div align="left">
|
|
65 Takahiro Sakamoto, Yu Tobaru, Shinji Kono
|
|
66 琉球大学工学部情報工学科並列信頼研
|
|
67 <hr style="color:#ffcc00;background-color:#ffcc00;text-align:left;border:none;width:100%;height:0.2em;">
|
|
68 </div>
|
|
69 </td>
|
|
70 </tr>
|
|
71 </table>
|
|
72 </div>
|
|
73
|
|
74
|
|
75 <div class='slide'>
|
18
|
76
|
|
77 <!-- _S9SLIDE_ -->
|
|
78 <h2 id="研究目的">研究目的</h2>
|
|
79 <ul>
|
|
80 <li>現代の OS では拡張性と信頼性を両立させることが要求されている</li>
|
|
81 <li>信頼性をノーマルレベルの計算に対して保証し、拡張性をメタレベルの計算で実現することを目標に Gears OS を設計中である</li>
|
|
82 <li>ノーマルレベルの計算とメタレベルの計算を切り離して記述するために Code Gear と Data Gear という単位を用いている</li>
|
20
|
83 </ul>
|
|
84
|
|
85
|
|
86
|
|
87 </div>
|
|
88
|
|
89 <div class='slide'>
|
|
90 <!-- _S9SLIDE_ -->
|
|
91 <h2 id="研究目的-1">研究目的</h2>
|
|
92 <ul>
|
18
|
93 <li>Gears OS は Continuation based C(CbC) によってアプリケーションと OS そのものを記述する</li>
|
|
94 <li>本研究では、CbC を用いた Gears OS の実装の前段階として xv6 での実装を目標とする</li>
|
|
95 </ul>
|
|
96
|
16
|
97
|
|
98
|
18
|
99 </div>
|
|
100
|
|
101 <div class='slide'>
|
|
102 <!-- _S9SLIDE_ -->
|
|
103 <h2 id="メタ計算とは">メタ計算とは</h2>
|
|
104 <ul>
|
|
105 <li>プログラムを記述する際、ノーマルレベルの処理の他に、メモリ管理やスレッド管理、CPU や GPU の資源管理等、記述しなければならない処理が存在する</li>
|
|
106 <li>これらの計算をメタ計算と呼ぶ</li>
|
|
107 <li>メタ計算はノーマルレベルの計算から切り離して記述したい</li>
|
20
|
108 </ul>
|
|
109
|
|
110
|
|
111
|
|
112 </div>
|
|
113
|
|
114 <div class='slide'>
|
|
115 <!-- _S9SLIDE_ -->
|
|
116 <h2 id="メタ計算とは-1">メタ計算とは</h2>
|
|
117 <ul>
|
18
|
118 <li>そのためには処理を細かく分割する必要があるが、関数やクラスなどの単位は容易に分割できない</li>
|
|
119 <li>そこで当研究室ではメタ計算を柔軟に記述するためのプログラミング言語の単位として Code Gear、Data Gear という単位を提案している</li>
|
|
120 </ul>
|
16
|
121
|
|
122
|
|
123
|
|
124 </div>
|
|
125
|
|
126 <div class='slide'>
|
|
127 <!-- _S9SLIDE_ -->
|
17
|
128 <h2 id="continuatuin-based-c">Continuatuin based C</h2>
|
16
|
129 <ul>
|
18
|
130 <li>Continuation based C (CbC) はこの Code Gear 処理の単位としてプログラミング言語として開発している。</li>
|
|
131 <li>Code Gear は 関数呼び出し時の環境を使わずに次の Code Gear へと goto 文によって遷移する</li>
|
20
|
132 <li>この goto 文による遷移を軽量継続と呼ぶ</li>
|
18
|
133 <li>継続を用いることによって状態遷移ベースでのプログラミングが可能である</li>
|
|
134 <li>CbC は C と互換性のある言語なので、C の関数も呼び出すことができる</li>
|
16
|
135 </ul>
|
|
136
|
|
137
|
|
138
|
|
139 </div>
|
|
140
|
|
141 <div class='slide'>
|
|
142 <!-- _S9SLIDE_ -->
|
17
|
143 <h2 id="cbc-のコード例">CbC のコード例</h2>
|
16
|
144 <ul>
|
20
|
145 <li>CbC では Code Gear は __code Code Gear 名 (引数) の形で記述される</li>
|
18
|
146 <li>Code Gear は戻り値を持たないので、関数とは異なり return 文は存在しない</li>
|
|
147 <li>goto の後に Code Gear 名と引数を並べて、次の Code Gear の遷移を記述する</li>
|
|
148 </ul>
|
|
149
|
|
150
|
|
151
|
|
152 </div>
|
|
153
|
|
154 <div class='slide'>
|
|
155 <!-- _S9SLIDE_ -->
|
|
156 <h2 id="cbc-のコード例-1">CbC のコード例</h2>
|
|
157 <ul>
|
|
158 <li>この goto の行き先を継続と呼び、このときの a+b が次の Code Gear への出力となる</li>
|
16
|
159 </ul>
|
|
160
|
17
|
161 <pre><code>__code cg0(int a, int b){
|
16
|
162 goto cg1(a+b);
|
17
|
163 }
|
16
|
164
|
17
|
165 __code cg1(int c){
|
16
|
166 goto cg2(c);
|
17
|
167 }
|
|
168 </code></pre>
|
16
|
169
|
|
170
|
|
171
|
|
172 </div>
|
|
173
|
|
174 <div class='slide'>
|
|
175 <!-- _S9SLIDE_ -->
|
18
|
176 <h2 id="cbc-の継続">CbC の継続</h2>
|
|
177 <ul>
|
|
178 <li>Code Gear の継続を表す図である</li>
|
19
|
179 <li>Code Gear 間の遷移は goto によって行われる
|
|
180 <!--* アセンブラレベルで見ると call ではなく jmp となっている--></li>
|
18
|
181 </ul>
|
|
182
|
|
183 <div style="text-align: center;">
|
19
|
184 <img src="./images/cbc_goto.svg" alt="normalCodeGear" width="600" />
|
18
|
185 </div>
|
|
186
|
|
187
|
|
188
|
|
189 </div>
|
|
190
|
|
191 <div class='slide'>
|
|
192 <!-- _S9SLIDE_ -->
|
17
|
193 <h2 id="gears-におけるメタ計算">Gears におけるメタ計算</h2>
|
16
|
194 <ul>
|
18
|
195 <li>Gears OS ではメタ計算を Meta Code Gear、Meta Data Gear で表現する</li>
|
|
196 <li>Meta Code Gear はノーマルレベルの Code Gear の直後に遷移され、メタ計算を実行する</li>
|
|
197 <li>Meta Code Gear で OS の機能であるメモリ管理やスレッド管理を行う</li>
|
16
|
198 </ul>
|
19
|
199 <div style="text-align: center;">
|
|
200 <img src="./images/meta_Code_Gear.svg" alt="normalCodeGear" width="600" />
|
|
201 </div>
|
|
202
|
|
203
|
|
204
|
|
205 </div>
|
|
206
|
|
207 <div class='slide'>
|
|
208 <!-- _S9SLIDE_ -->
|
|
209 <h2 id="meta-gear">Meta Gear</h2>
|
|
210 <ul>
|
|
211 <li>Gears OS では、Meta Code Gear は通常の Code Gear の直前、直後に挿入され、メタ計算を実行する</li>
|
|
212 <li>通常の計算からはメタ計算は見ることができない</li>
|
|
213 </ul>
|
|
214 <div style="text-align: center;">
|
|
215 <img src="./images/meta_gear2.svg" alt="MetaGear" width="600" />
|
|
216 </div>
|
|
217
|
|
218
|
|
219
|
|
220 </div>
|
|
221
|
|
222 <div class='slide'>
|
|
223 <!-- _S9SLIDE_ -->
|
|
224 <h2 id="context">Context</h2>
|
|
225 <ul>
|
|
226 <li>Gears OS では Context と呼ばれる、使用されるすべての Code Gear、Data Gear を持つ Meta Data Gear を持っている</li>
|
|
227 <li>Gears OS は必要な Code Gear、Data Gear を参照したい場合、この Context を通す必要がある</li>
|
|
228 <li>Context は Meta Data Gear であるため、Meta Code Gear を介してアクセスする</li>
|
|
229 </ul>
|
|
230
|
16
|
231
|
|
232
|
|
233 </div>
|
|
234
|
|
235 <div class='slide'>
|
|
236 <!-- _S9SLIDE_ -->
|
20
|
237 <h2 id="context-1">Context</h2>
|
|
238 <ul>
|
|
239 <li>Context は全ての Code Gear のリストを持っており、enum で番号とアドレスを対応付けている
|
|
240 <pre><code>enum Code {
|
|
241 C_popSingleLinkedStack,
|
|
242 C_pushSingleLinkedStack,
|
|
243 C_stackTest3,
|
|
244 C_assert3,
|
|
245 ...
|
|
246 };
|
|
247 </code></pre>
|
|
248 <pre><code>context->code[C_popSingleLinkedStack] = popSingleLinkedStack_stub;
|
|
249 context->code[C_pushSingleLinkedStack] = pushSingleLinkedStack_stub;
|
|
250 context->code[C_stackTest3] = stackTest3_stub;
|
|
251 context->code[C_assert3] = assert3_stub;
|
|
252 </code></pre>
|
|
253 </li>
|
|
254 </ul>
|
|
255
|
|
256
|
|
257
|
|
258 </div>
|
|
259
|
|
260 <div class='slide'>
|
|
261 <!-- _S9SLIDE_ -->
|
|
262 <h2 id="context-2">Context</h2>
|
|
263 <ul>
|
|
264 <li>Data Gear も Code Gear と同様に Context が全ての Data Gear のリストを持っている</li>
|
|
265 <li>Data Gear のリストも enum で管理されている</li>
|
|
266 <li>これは引数格納用の Data Gear の番号である
|
|
267 <pre><code>enum DataType {
|
|
268 D_Code,
|
|
269 D_SingleLinkedStack,
|
|
270 D_Stack,
|
|
271 D_TaskManager,
|
|
272 D_Worker,
|
|
273 ...
|
|
274 };
|
|
275 </code></pre>
|
|
276 </li>
|
|
277 </ul>
|
|
278
|
|
279
|
|
280
|
|
281 </div>
|
|
282
|
|
283 <div class='slide'>
|
|
284 <!-- _S9SLIDE_ -->
|
17
|
285 <h2 id="interface">Interface</h2>
|
16
|
286 <ul>
|
18
|
287 <li>Code Gear と Data Gear は Interface と呼ばれるまとまりとして記述される</li>
|
20
|
288 <li>Interface は GearsOS でのモジュール化の仕組み</li>
|
18
|
289 <li>Interface は使用される Data Gear の定義と、それに対する Code Gear の集合である</li>
|
|
290 <li>Interface の操作に対応する Code Gear の引数は Interface に定義されている Data Gear を通して行われる</li>
|
|
291 </ul>
|
|
292
|
|
293
|
|
294
|
|
295 </div>
|
|
296
|
|
297 <div class='slide'>
|
|
298 <!-- _S9SLIDE_ -->
|
20
|
299 <h2 id="interface-の定義">Interface の定義</h2>
|
|
300 <ul>
|
|
301 <li>Stack の Interface の例である</li>
|
|
302 <li>typedef struct Interface 名で記述する</li>
|
|
303 <li>Impl は実際に実装した際のデータ構造の型になる</li>
|
|
304 </ul>
|
|
305
|
|
306 <pre><code>typedef struct Stack<Impl> {
|
|
307 union Data* stack;
|
|
308 union Data* data;
|
|
309 __code next(...);
|
|
310 __code whenEmpty(...);
|
|
311
|
|
312 __code clear(Impl* stack, __code next(...));
|
|
313 __code push(Impl* stack, union Data* data, __code next(...));
|
|
314 __code pop(Impl* stack, __code next(union Data* ...));
|
|
315 __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...));
|
|
316
|
|
317 }
|
|
318 </code></pre>
|
|
319
|
|
320
|
|
321 </div>
|
|
322
|
|
323 <div class='slide'>
|
|
324 <!-- _S9SLIDE_ -->
|
|
325 <h2 id="interface-の定義-1">Interface の定義</h2>
|
|
326 <ul>
|
|
327 <li>Data Gear は 操作する Data Gear と
|
|
328 操作に必要な全ての Data Gear Gear が記述されている</li>
|
|
329 <li>__code で記述されているものが操作の Code Gear である</li>
|
|
330 </ul>
|
|
331
|
|
332 <pre><code>typedef struct Stack<Impl> {
|
|
333 union Data* stack;
|
|
334 union Data* data;
|
|
335 __code next(...);
|
|
336 __code whenEmpty(...);
|
|
337
|
|
338 __code clear(Impl* stack, __code next(...));
|
|
339 __code push(Impl* stack, union Data* data, __code next(...));
|
|
340 __code pop(Impl* stack, __code next(union Data* ...));
|
|
341 __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...));
|
|
342
|
|
343 }
|
|
344 </code></pre>
|
|
345
|
|
346
|
|
347 </div>
|
|
348
|
|
349 <div class='slide'>
|
|
350 <!-- _S9SLIDE_ -->
|
|
351 <h2 id="interface-の実装の記述">Interface の実装の記述</h2>
|
|
352 <ul>
|
|
353 <li>ソースコードは Interface の実装の初期化のコードである</li>
|
|
354 <li>操作の Code Gear には実装した Code Gear の番号が代入されるが、ここを入れ替えることで、複数の実装を持つことができる
|
|
355 <pre><code>Stack* createSingleLinkedStack(struct Context* context) {
|
|
356 struct Stack* stack = new Stack();
|
|
357 struct SingleLinkedStack* singleLinkedStack = new SingleLinkedStack();
|
|
358 stack->stack = (union Data*)singleLinkedStack;
|
|
359 singleLinkedStack->top = NULL;
|
|
360 stack->push = C_pushSingleLinkedStack;
|
|
361 stack->pop = C_popSingleLinkedStack;
|
|
362 stack->isEmpty = C_isEmptySingleLinkedStack;
|
|
363 stack->clear = C_clearSingleLinkedStack;
|
|
364 return stack;
|
|
365 }
|
|
366 </code></pre>
|
|
367 </li>
|
|
368 </ul>
|
|
369
|
|
370
|
|
371
|
|
372 </div>
|
|
373
|
|
374 <div class='slide'>
|
|
375 <!-- _S9SLIDE_ -->
|
18
|
376 <h2 id="xv6-rpi-の-cbc-対応">xv6-rpi の CbC 対応</h2>
|
|
377 <ul>
|
|
378 <li>オリジナルの xv6 は x86 アーキテクチャで実装されたものだが、xv6-rpi は Raspberry Pi 用に実装されたものである</li>
|
|
379 <li>xv6-rpi を CbC で書き換えるために、GCC 上で実装した CbC コンパイラを ARM 向けに build し xv6-rpi をコンパイルした</li>
|
|
380 <li>これにより、xv6-rpi を CbC で書き換える ことができるようになった</li>
|
16
|
381 </ul>
|
|
382
|
|
383
|
|
384
|
|
385 </div>
|
|
386
|
|
387 <div class='slide'>
|
|
388 <!-- _S9SLIDE_ -->
|
17
|
389 <h2 id="xv6-の-cbc-への書き換え">xv6 の CbC への書き換え</h2>
|
18
|
390 <ul>
|
|
391 <li>xv6 は UNIX V6 を x86 向けに再実装した OS である</li>
|
|
392 <li>プロセスや仮想メモリ、カーネルとユーザーの分離、割り込み、ファイルシステムなどの基本的な Unix の構造を持つ</li>
|
|
393 <li>CbC は Code Gear 間の遷移が goto による継続で行われるため、状態遷移ベースでのプログラミングに適している</li>
|
|
394 <li>CbC で xv6 を書き換えることにより、状態遷移モデルによるモデル検査が可能となることを期待する</li>
|
|
395 </ul>
|
16
|
396
|
|
397
|
|
398
|
|
399 </div>
|
|
400
|
|
401 <div class='slide'>
|
|
402 <!-- _S9SLIDE_ -->
|
18
|
403 <h2 id="xv6-の書き換えの方針">xv6 の書き換えの方針</h2>
|
|
404 <ul>
|
|
405 <li>xv6 を CbC で書き換え、Gears OS の機能と置き換えることで Gears OS に OS の基本構造を持たせたい</li>
|
|
406 <li>このためには xv6 をモジュール化することで、xv6 の機能を明らかにする必要がある</li>
|
|
407 <li>xv6 の Interface を定義し、Gears OS の機能をこれに合わせることによって実現したい</li>
|
|
408 </ul>
|
16
|
409
|
|
410
|
|
411
|
|
412 </div>
|
|
413
|
|
414 <div class='slide'>
|
|
415 <!-- _S9SLIDE_ -->
|
17
|
416 <h2 id="cbc-によるシステムコールの書き換え">CbC によるシステムコールの書き換え</h2>
|
18
|
417 <ul>
|
|
418 <li>CbC は C と互換性のある言語であるため、元のソースコードから大きく崩すことなく必要な機能のみを CbC へと書き換えることが可能である</li>
|
|
419 <li>ここでは実際にシステムコールを CbC で書き換えることによって、状態遷移ベースで書き換えるには何が必要か示すことにした</li>
|
|
420 <li>今回は read システムコールの CbC 書き換えを行なった</li>
|
|
421 </ul>
|
|
422
|
|
423
|
|
424
|
|
425 </div>
|
|
426
|
|
427 <div class='slide'>
|
|
428 <!-- _S9SLIDE_ -->
|
19
|
429 <h2 id="syscall関数">syscall関数</h2>
|
|
430 <ul>
|
|
431 <li>syscall 関数 はシステムコールを呼び出す関数である
|
|
432 <pre><code>void syscall(void)
|
|
433 {
|
|
434 int num;
|
|
435 int ret;
|
|
436 num = proc->tf->r0;
|
|
437 if((num >= NELEM(syscalls)) && (num <= NELEM(cbccodes)) && cbccodes[num]) {
|
|
438 proc->cbc_arg.cbc_console_arg.num = num;
|
|
439 goto (cbccodes[num])(cbc_ret);
|
|
440 }
|
|
441 if((num > 0) && (num <= NELEM(syscalls)) && syscalls[num]) {
|
|
442 ret = syscalls[num]();
|
|
443 if (num != SYS_exec) {
|
|
444 proc->tf->r0 = ret;
|
|
445 }
|
|
446 } else {
|
|
447 cprintf("%d %s: unknown sys call %d\n", proc->pid, proc->name, num);
|
|
448 proc->tf->r0 = -1;
|
|
449 }
|
|
450 }
|
|
451 </code></pre>
|
|
452 </li>
|
|
453 </ul>
|
|
454
|
|
455
|
|
456
|
|
457 </div>
|
|
458
|
|
459 <div class='slide'>
|
|
460 <!-- _S9SLIDE_ -->
|
18
|
461 <h2 id="sys_read-関数">sys_read 関数</h2>
|
|
462 <ul>
|
|
463 <li>読み込むファイルの情報とアドレスを取り出し、fileread に渡している
|
|
464 <pre><code>int sys_read(void)
|
|
465 {
|
|
466 struct file *f;
|
|
467 int n;
|
|
468 char *p;
|
|
469
|
|
470 if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) {
|
|
471 return -1;
|
|
472 }
|
|
473
|
|
474 return fileread(f, p, n);
|
|
475 }
|
|
476 </code></pre>
|
|
477 </li>
|
|
478 </ul>
|
|
479
|
|
480
|
|
481
|
|
482 </div>
|
|
483
|
|
484 <div class='slide'>
|
|
485 <!-- _S9SLIDE_ -->
|
|
486 <h2 id="cbc_read">cbc_read</h2>
|
|
487 <pre><code>__code cbc_read(__code (*next)(int ret)){
|
|
488 struct file *f;
|
|
489 int n;
|
|
490 char *p;
|
|
491
|
|
492 if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) {
|
|
493 goto next(-1);
|
|
494 }
|
|
495 goto cbc_fileread(f, p, n, next);
|
|
496 }
|
|
497 </code></pre>
|
|
498
|
|
499
|
|
500
|
|
501 </div>
|
|
502
|
|
503 <div class='slide'>
|
|
504 <!-- _S9SLIDE_ -->
|
|
505 <h2 id="fileread">fileread</h2>
|
|
506 <ul>
|
|
507 <li>file の状態を確認し、対応した関数へ移行する
|
|
508 <pre><code>int fileread (struct file *f, char *addr, int n)
|
|
509 {
|
|
510 int r;
|
|
511
|
|
512 if (f->readable == 0) {
|
|
513 return -1;
|
|
514 }
|
|
515
|
|
516 if (f->type == FD_PIPE) {
|
|
517 return piperead(f->pipe, addr, n);
|
|
518 }
|
|
519
|
|
520 if (f->type == FD_INODE) {
|
|
521 ilock(f->ip);
|
|
522
|
|
523 if ((r = readi(f->ip, addr, f->off, n)) > 0) {
|
|
524 f->off += r;
|
|
525 }
|
|
526
|
|
527 iunlock(f->ip);
|
|
528
|
|
529 return r;
|
|
530 }
|
|
531
|
|
532 panic("fileread");
|
|
533 }
|
|
534 </code></pre>
|
|
535 </li>
|
|
536 </ul>
|
|
537
|
|
538
|
|
539
|
|
540 </div>
|
|
541
|
|
542 <div class='slide'>
|
|
543 <!-- _S9SLIDE_ -->
|
|
544 <h2 id="cbc_fileread">cbc_fileread</h2>
|
|
545 <pre><code>__code cbc_fileread1 (int r)
|
|
546 {
|
|
547 struct file *f = proc->cbc_arg.cbc_console_arg.f;
|
|
548 __code (*next)(int ret) = cbc_ret;
|
|
549 if (r > 0)
|
|
550 f->off += r;
|
|
551 iunlock(f->ip);
|
|
552 goto next(r);
|
|
553 }
|
|
554
|
|
555 __code cbc_fileread (struct file *f, char *addr, int n, __code (*next)(int ret))
|
|
556 {
|
|
557 if (f->readable == 0) {
|
|
558 goto next(-1);
|
|
559 }
|
|
560
|
|
561 if (f->type == FD_PIPE) {
|
|
562 //goto cbc_piperead(f->pipe, addr, n, next);
|
|
563 goto next(-1);
|
|
564 }
|
|
565
|
|
566 if (f->type == FD_INODE) {
|
|
567 ilock(f->ip);
|
|
568 proc->cbc_arg.cbc_console_arg.f = f;
|
|
569 goto cbc_readi(f->ip, addr, f->off, n, cbc_fileread1);
|
|
570 }
|
|
571
|
|
572 goto cbc_panic("fileread");
|
|
573 }
|
|
574 </code></pre>
|
|
575
|
|
576
|
|
577
|
|
578 </div>
|
|
579
|
|
580 <div class='slide'>
|
|
581 <!-- _S9SLIDE_ -->
|
|
582 <h2 id="readi">readi</h2>
|
|
583 <ul>
|
|
584 <li>readi はファイルシステム上か特殊なデバイスを制御するかどうかで分岐する</li>
|
|
585 <li>ここでは consoleread へ向かう処理を確認する
|
|
586 <pre><code>int readi (struct inode *ip, char *dst, uint off, uint n)
|
|
587 {
|
|
588 uint tot, m;
|
|
589 struct buf *bp;
|
|
590
|
|
591 if (ip->type == T_DEV) {
|
|
592 if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read) {
|
|
593 return -1;
|
|
594 }
|
|
595
|
|
596 return devsw[ip->major].read(ip, dst, n);
|
|
597 }
|
|
598 ...
|
|
599 </code></pre>
|
|
600 </li>
|
|
601 </ul>
|
|
602
|
|
603
|
|
604
|
|
605 </div>
|
|
606
|
|
607 <div class='slide'>
|
|
608 <!-- _S9SLIDE_ -->
|
|
609 <h2 id="cbc_readi">cbc_readi</h2>
|
|
610 <pre><code>__code cbc_readi (struct inode *ip, char *dst, uint off, uint n, __code (*next)(int ret))
|
|
611 {
|
|
612 uint tot, m;
|
|
613 struct buf *bp;
|
|
614
|
|
615 if (ip->type == T_DEV) {
|
|
616 if (ip->major < 0 || ip->major >= NDEV || !cbc_devsw[ip->major].read) {
|
|
617 goto next(-1);
|
|
618 }
|
|
619
|
|
620 goto cbc_devsw[ip->major].read(ip, dst, n, next);
|
|
621 }
|
|
622 ...
|
|
623 </code></pre>
|
|
624
|
|
625
|
|
626
|
|
627 </div>
|
|
628
|
|
629 <div class='slide'>
|
|
630 <!-- _S9SLIDE_ -->
|
|
631 <h2 id="consoleread">consoleread</h2>
|
|
632 <ul>
|
|
633 <li>console への入力を読み込み、待っている間スリープする
|
|
634 <pre><code>int consoleread (struct inode *ip, char *dst, int n)
|
|
635 {
|
|
636 uint target;
|
|
637 int c;
|
|
638 iunlock(ip);
|
|
639 target = n;
|
|
640 acquire(&input.lock);
|
|
641
|
|
642 while (n > 0) {
|
|
643 while (input.r == input.w) {
|
|
644 if (proc->killed) {
|
|
645 release(&input.lock);
|
|
646 ilock(ip);
|
|
647 return -1;
|
|
648 }
|
|
649 sleep(&input.r, &input.lock);
|
|
650 }
|
|
651 c = input.buf[input.r++ % INPUT_BUF];
|
|
652 if (c == C('D')) { // EOF
|
|
653 if (n < target) {
|
|
654 input.r--;
|
|
655 }
|
|
656 break;
|
|
657 }
|
|
658 *dst++ = c;
|
|
659 --n;
|
|
660 if (c == '\n') {
|
|
661 break;
|
|
662 }
|
|
663 }
|
|
664 release(&input.lock);
|
|
665 ilock(ip);
|
|
666 return target - n;
|
|
667 }
|
|
668 </code></pre>
|
|
669 </li>
|
|
670 </ul>
|
|
671
|
|
672
|
|
673
|
|
674 </div>
|
|
675
|
|
676 <div class='slide'>
|
|
677 <!-- _S9SLIDE_ -->
|
|
678 <h2 id="cbc_consoleread">cbc_consoleread</h2>
|
|
679
|
|
680 <pre><code>__code cbc_consoleread (struct inode *ip, char *dst, int n, __code(*next)(int ret))
|
|
681 {
|
|
682 uint target;
|
|
683
|
|
684 iunlock(ip);
|
|
685
|
|
686 target = n;
|
|
687 acquire(&input.lock);
|
|
688
|
|
689 if (n > 0) {
|
|
690 proc->cbc_arg.cbc_console_arg.n = n;
|
|
691 proc->cbc_arg.cbc_console_arg.target = target;
|
|
692 proc->cbc_arg.cbc_console_arg.dst = dst;
|
|
693 proc->cbc_arg.cbc_console_arg.ip = ip;
|
|
694 proc->cbc_arg.cbc_console_arg.next = next;
|
|
695 goto cbc_consoleread2();
|
|
696 }
|
|
697 goto cbc_consoleread1();
|
|
698 }
|
|
699 </code></pre>
|
|
700
|
|
701
|
|
702
|
|
703 </div>
|
|
704
|
|
705 <div class='slide'>
|
|
706 <!-- _S9SLIDE_ -->
|
|
707 <h2 id="cbc_consoleread-1">cbc_consoleread</h2>
|
|
708 <pre><code>__code cbc_consoleread2 ()
|
|
709 {
|
|
710 struct inode *ip = proc->cbc_arg.cbc_console_arg.ip;
|
|
711 __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next;
|
|
712 if (input.r == input.w) {
|
|
713 if (proc->killed) {
|
|
714 release(&input.lock);
|
|
715 ilock(ip);
|
|
716 goto next(-1);
|
|
717 }
|
|
718 goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2);
|
|
719 }
|
|
720 goto cbc_consoleread1();
|
|
721 }
|
|
722
|
|
723 __code cbc_consoleread1 ()
|
|
724 {
|
|
725 int cont = 1;
|
|
726 int n = proc->cbc_arg.cbc_console_arg.n;
|
|
727 int target = proc->cbc_arg.cbc_console_arg.target;
|
|
728 char* dst = proc->cbc_arg.cbc_console_arg.dst;
|
|
729 struct inode *ip = proc->cbc_arg.cbc_console_arg.ip;
|
|
730 __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next;
|
|
731
|
|
732 int c = input.buf[input.r++ % INPUT_BUF];
|
|
733
|
|
734 if (c == C('D')) { // EOF
|
|
735 if (n < target) {
|
|
736 input.r--;
|
|
737 }
|
|
738 cont = 0;
|
|
739 }
|
|
740
|
|
741 *dst++ = c;
|
|
742 --n;
|
|
743 if (c == '\n') {
|
|
744 cont = 0;
|
|
745 }
|
|
746 if (cont == 1) {
|
|
747 if (n > 0) {
|
|
748 proc->cbc_arg.cbc_console_arg.n = n;
|
|
749 proc->cbc_arg.cbc_console_arg.target = target;
|
|
750 proc->cbc_arg.cbc_console_arg.dst = dst;
|
|
751 proc->cbc_arg.cbc_console_arg.ip = ip;
|
|
752 proc->cbc_arg.cbc_console_arg.next = next;
|
|
753 goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2);
|
|
754 }
|
|
755 }
|
|
756 release(&input.lock);
|
|
757 ilock(ip);
|
|
758 goto next(target - n);
|
|
759 }
|
|
760 </code></pre>
|
|
761
|
|
762
|
|
763 </div>
|
|
764
|
|
765 <div class='slide'>
|
|
766 <!-- _S9SLIDE_ -->
|
|
767 <h2 id="sleep">sleep</h2>
|
|
768 <ul>
|
|
769 <li>プロセスをスリープ状態にしてスケジューラーへ引き渡す
|
|
770 <pre><code>void sleep(void *chan, struct spinlock *lk)
|
|
771 {
|
|
772 if(proc == 0) {
|
|
773 panic("sleep");
|
|
774 }
|
|
775
|
|
776 if(lk == 0) {
|
|
777 panic("sleep without lk");
|
|
778 }
|
|
779
|
|
780 if(lk != &ptable.lock){ //DOC: sleeplock0
|
|
781 acquire(&ptable.lock); //DOC: sleeplock1
|
|
782 release(lk);
|
|
783 }
|
|
784
|
|
785 proc->chan = chan;
|
|
786 proc->state = SLEEPING;
|
|
787 sched();
|
|
788
|
|
789 proc->chan = 0;
|
|
790
|
|
791 if(lk != &ptable.lock){ //DOC: sleeplock2
|
|
792 release(&ptable.lock);
|
|
793 acquire(lk);
|
|
794 }
|
|
795 }
|
|
796 </code></pre>
|
|
797 </li>
|
|
798 </ul>
|
|
799
|
|
800
|
|
801
|
|
802 </div>
|
|
803
|
|
804 <div class='slide'>
|
|
805 <!-- _S9SLIDE_ -->
|
|
806 <h2 id="cbc_sleep">cbc_sleep</h2>
|
|
807 <pre><code>__code cbc_sleep1()
|
|
808 {
|
|
809 struct spinlock *lk = proc->lk;
|
|
810 proc->chan = 0;
|
|
811
|
|
812 if(lk != &ptable.lock){ //DOC: sleeplock2
|
|
813 release(&ptable.lock);
|
|
814 acquire(lk);
|
|
815 }
|
|
816 goto proc->cbc_next();
|
|
817 }
|
|
818
|
|
819 __code cbc_sleep(void *chan, struct spinlock *lk, __code(*next1)())
|
|
820 {
|
|
821 if(proc == 0) {
|
|
822 panic("sleep");
|
|
823 }
|
|
824
|
|
825 if(lk == 0) {
|
|
826 panic("sleep without lk");
|
|
827 }
|
|
828
|
|
829 if(lk != &ptable.lock){ //DOC: sleeplock0
|
|
830 acquire(&ptable.lock); //DOC: sleeplock1
|
|
831 release(lk);
|
|
832 }
|
|
833 proc->chan = chan;
|
|
834 proc->state = SLEEPING;
|
|
835 proc->lk = lk;
|
|
836 proc->cbc_next = next1;
|
|
837
|
|
838 goto cbc_sched(cbc_sleep1);
|
|
839 }
|
|
840 </code></pre>
|
|
841
|
|
842
|
|
843
|
|
844 </div>
|
|
845
|
|
846 <div class='slide'>
|
|
847 <!-- _S9SLIDE_ -->
|
|
848 <h2 id="sched">sched</h2>
|
|
849 <ul>
|
|
850 <li>レジスタの値を切り替えて、スケジューラーへと戻る</li>
|
|
851 <li>再開時は swtch の下から再開する
|
|
852 <pre><code>void sched(void)
|
|
853 {
|
|
854 int intena;
|
|
855
|
|
856 if(!holding(&ptable.lock)) {
|
|
857 panic("sched ptable.lock");
|
|
858 }
|
|
859
|
|
860 if(cpu->ncli != 1) {
|
|
861 panic("sched locks");
|
|
862 }
|
|
863
|
|
864 if(proc->state == RUNNING) {
|
|
865 panic("sched running");
|
|
866 }
|
|
867
|
|
868 if(int_enabled ()) {
|
|
869 panic("sched interruptible");
|
|
870 }
|
|
871
|
|
872 intena = cpu->intena;
|
|
873 swtch(&proc->context, cpu->scheduler);
|
|
874 cpu->intena = intena;
|
|
875 }
|
|
876 </code></pre>
|
|
877 </li>
|
|
878 </ul>
|
|
879
|
|
880
|
|
881
|
|
882 </div>
|
|
883
|
|
884 <div class='slide'>
|
|
885 <!-- _S9SLIDE_ -->
|
|
886 <h2 id="cbc_sched">cbc_sched</h2>
|
|
887 <pre><code>__code cbc_sched(__code(*next)())
|
|
888 {
|
|
889 int intena;
|
|
890
|
|
891 if(!holding(&ptable.lock)) {
|
|
892 panic("sched ptable.lock");
|
|
893 }
|
|
894
|
|
895 if(cpu->ncli != 1) {
|
|
896 panic("sched locks");
|
|
897 }
|
|
898
|
|
899 if(proc->state == RUNNING) {
|
|
900 panic("sched running");
|
|
901 }
|
|
902
|
|
903 if(int_enabled ()) {
|
|
904 panic("sched interruptible");
|
|
905 }
|
|
906
|
|
907 intena = cpu->intena;
|
|
908 swtch(&proc->context, cpu->scheduler);
|
|
909 cpu->intena = intena;
|
|
910
|
|
911 goto next();
|
|
912 }
|
|
913 </code></pre>
|
19
|
914 <!-- コメントアウトのやり方-->
|
16
|
915
|
|
916
|
|
917 </div>
|
|
918
|
|
919 <div class='slide'>
|
|
920 <!-- _S9SLIDE_ -->
|
17
|
921 <h2 id="まとめと今後の方針">まとめと今後の方針</h2>
|
18
|
922 <ul>
|
|
923 <li>現在は xv6 のシステムコールの一部のみの書き換えと、設計のみしか行っていないのでカーネル全ての書き換えをおこなう</li>
|
|
924 <li>Gears OS にはメタ計算を実装する context は par goto の機能がある</li>
|
|
925 <li>これらの機能を xv6 に組み込む方法について考察する必要がある</li>
|
|
926 <li>xv6-rpi は QEMU のみの動作でしか確認してないため、実機上での動作が可能なように実装する必要がある</li>
|
|
927 </ul>
|
16
|
928
|
|
929 </div>
|
|
930
|
|
931
|
|
932 </div><!-- presentation -->
|
|
933 </body>
|
|
934 </html>
|