2009년 08월 17일
Scheduler의 구현
1) 다음에 순서를 받을 Task 선정
2) Context Switching을 해야겠죠. 어떻게? 현재 Running Task의 Context 를 해당 Task의 Stack에 저장하고, 다음 번 순서의 Task의 Stack에서 Context를 CPU Register로 가져오는 일을 해서 그 일을 마무리 하는 거죠.
1) 다음 순서를 받을 Task를 선정하는 방법 - 가장 높은 Priority를 가진 Ready Task를 선정하는 방법. 다음에 순서를 받을 Task를 선정하는 방법에는 여러 가지 방법이 있어요. Priority base 같은 경우에는 Priority 순서대로 TCB를 Linked List로 연결해서 묶어 놓은 후에, TCB를 묶어 놓은 Head부터 점차 하나하나 Ready된 Task를 찾아가는 걸로 다음 Task를 결정할 수도 있고요.
이렇게 Ready된 Task를 찾아가는 게 시간이 걸리니까, Ready Task만 다로 Ready Task List로 따로 관리하는 방법도 있어요. 그런 경우에는 send_signal() 내부에 Ready 시킨 Task를 Ready Task List에 넣어주는 수고로움을 해줘야 한답니다.
여하튼 간에 그 모양새는 (Priority 높은 순서대로.)

(이런 방법은 Task가 많을 수록 Highest Priority Task를 찾는데 시간이 걸리겠죠.) 이것 때문에 여러 가지 방법들이 많이 나오는데, 요즘은 computing power가 좋아져서 이 방법도 꽤나 쓸모 있으니, 참고해 두세요.
그러면 실제 Context Switching은 어떻게 할 거냐. 하면! 현재 context를 해당 task의 stack에 집어 넣는 일을 해야겠죠. 그건 Assembly로 가능하니까, 그 예를 들어보도록 하겠나이다.
msr SPSR_c, r0 ; c자리를 update해 주시고,
N _ R0 01E4 R8 0 SP> 00000001
Z _ R1 01154808 R9 0 +04 01141EC0
C C R2 600000D3 R10 011416C0 +08 010A82E0
V _ R3 01141EC0 R11 0 +0C 0005FC27
I I R4 6007 R12 007A70A1 +10 00000000
F F R5 0 R13 01141E8C +14 00000000
T _ R6 00FE8038 R14 0B49 +18 00000000
J _ R7 03BB PC 00011218 +1C 00000000
svc SPSR 600000F3 CPSR 200000D3 +20 00000000
Q _ +24 00000D29
USR: FIQ: +28 00000000
R8 0 R8 0 +2C 00000D21
R9 0 R9 0 +30 00000000
R10 011416C0 R10 0 +34 01141E4C
R11 0 R11 0 +38 011416C0
R12 007A70A1 R12 0 +3C 00000007
R13 00FEE730 R13 00FEC8A0 +40 00000000
R14 0 R14 0 +44 00006007
SPSR 10 +48 0000002B
+4C 00000000
SVC: IRQ: +50 00000000
R13 01141E8C R13 00FED1A0 +54 00000000
R14 0B49 R14 00011290 +58 018A00D4
SPSR 600000F3 SPSR 60000013 +5C 0115CF50
+60 00000000
UND: ABT: +64 00000000
R13 00FEE830 R13 00FEDB30 +68 00FEBF88
R14 0 R14 0 +6C 00000000
SPSR 10 SPSR 10 +70 00000000
뒤따라 오는 그림은 Stack이 있는 곳에 대한 Memory 실제 모양새 이에요.일단은 어찌디었던 간에 Context Switching을 하기 위해서는,
___address__|________0________4________8________C_0123456789ABCDEF
SD:01141DE0| 0000E913 018A0154 018A00D4 018A0124 ....T.......$...
SD:01141DF0| 00095F3F 018A00D4 00FE8038 00000027 ?_......8...'...
SD:01141E00| 00000E15 00000000 018A00D4 018A02AC ................
SD:01141E10| 00000800 00000027 00000027 00000000 ....'...'.......
SD:01141E20| 007FE594 600000F3 00000E97 600000F3 .......`.......`
SD:01141E30| 00000000 007FE594 0115F2B0 00000000 ................
SD:01141E40| 00FE8038 00000000 00000000 600000F3 8..............`
SD:01141E50| 011416C0 00000000 00000000 00000000 ................
SD:01141E60| 00006007 00000000 00FE8038 00000000 .`......8.......
SD:01141E70| 010A82E0 000003BB 000003BB 00006007 .............`..
SD:01141E80| 00000000 000003BB 00000B45>00000001 ........E.......
SD:01141E90| 01141EC0 010A82E0 0005FC27 00000000 ........'.......
SD:01141EA0| 00000000 00000000 00000000 00000000 ................
___address__|________0________4________8________C_0123456789ABCDEF
SD:01141DE0| 0000E913 018A0154 018A00D4 018A0124 ....T.......$...
SD:01141DF0| 00095F3F 018A00D4 00FE8038 00000027 ?_......8...'...
SD:01141E00| 00000E15 00000000 018A00D4 018A02AC ................
SD:01141E10| 00000800 00000027 00000027 00000000 ....'...'.......
SD:01141E20| 007FE594 600000F3 00000E97 600000F3 .......`.......`
SD:01141E30| 00000000 007FE594 0115F2B0 00000000 ................
SD:01141E40| 00FE8038 00000000 018A02AC>200000D3 > : Push된 다음의 SP
SD:01141E50| 000001E4 01154808 600000D3 01141EC0 ................
SD:01141E60| 00006007 00000000 00FE8038 000003BB .`......8.......
SD:01141E70| 00000000 00000000 011416C0 00000000 .............`..
SD:01141E80| 007A70A1 000003BB 00000B49>00000001 > : 원래의 SP
SD:01141E90| 01141EC0 010A82E0 0005FC27 00000000 ........'.......
SD:01141EA0| 00000000 00000000 00000000 00000000 ................
즉
SD:01141DE0| 0000E913 018A0154 018A00D4 018A0124 ....T.......$...
SD:01141DF0| 00095F3F 018A00D4 00FE8038 00000027 ?_......8...'...
SD:01141E00| 00000E15 00000000 018A00D4 018A02AC ................
SD:01141E10| 00000800 00000027 00000027 00000000 ....'...'.......
SD:01141E20| 007FE594 600000F3 018A02AC 600000F3 .......`.......`
SD:01141E30| 00000000 007FE594 0115F2B0 00000000 ................
SD:01141E40| 00FE8038 00000000 600000F3>CPSR 8..............`
SD:01141E50| r0 r1 r2 r3 ................
SD:01141E60| r4 r5 r6 r7 .`......8.......
SD:01141E70| r8 r9 r10 r11 .............`..
SD:01141E80| r12 000003BB lr >00000001 ........E.......
SD:01141E90| 01141EC0 010A82E0 0005FC27 00000000 ........'.......
SD:01141EA0| 00000000 00000000 00000000 00000000 ................
뭐 이런 식인거죠. 거꾸로 Context를 복구할 때는 SP가 가르키는 곳부터 거꾸리 순서대로 restore해주면 되겠죠. 자, 그러면 미지의 Wait state의 Task의 TCB로 부터 lr을 찾아내어, 그 Task가 어디까지 실행한 후, Context Swtiching이 되었었는지 찾아 볼까요?
dsp_tcb = (
sp = 0x0113F114,
receive_signal = 0,
wait_signal = 24607,
pri = 125,
link = (next_ptr = 0x01142488, prev_ptr = 0x01140B10),
task_name = "DSP"}
뭐 이런식으로 생겼다고 보믄요,
___address__|________0________4________8________C_0123456789ABCDEF
SD:0113F110| 00B4BB87>600000F3 00000003 00FBF600 .......`........
SD:0113F120| 00000000 00000003 0000601F 00000000 .........`......
SD:0113F130| 00FE8038 0113F188 00000000 00000000 8...............
SD:0113F140| 0113ED88 00000000 00000000 0113F188 ................
SD:0113F150| 00000B49 00000001 010E8218 00000000 I...............
SD:0113F160| 00B4CA09 00000000 00000000 00000000 ................
SD:0113F170| 00000000 00000000 00000D29 00000000 ........).......
SD:0113F180| 00000D21 00000000 0113F114 0113ED88 !...............
SD:0113F190| 00000007 00000000 0000601F 0000007D .........`..}...
SD:0113F1A0| 00000000 00000000 00000000 01142488 .............$..
SD:0113F110| 00B4BB87>CPSR R0 R1 .......`........
SD:0113F120| R2 R3 R4 R5 .........`......
SD:0113F130| R6 R7 R8 R9 8...............
SD:0113F140| R10 R11 R12 0113F188 ................
SD:0113F150| lr 00000001 010E8218 00000000 I...............
SD:0113F160| 00B4CA09 00000000 00000000 00000000 ................
SD:0113F170| 00000000 00000000 00000D29 00000000 ........).......
SD:0113F180| 00000D21 00000000 0113F114 0113ED88 !...............
SD:0113F190| 00000007 00000000 0000601F 0000007D .........`..}...
SD:0113F1A0| 00000000 00000000 00000000 01142488 .............$..
| #endif
| }
1680| sigs = curr_task_tcb->sigs;
ST:00000B48|6AB0 ldr r0,[r6,#0x28]
1681| INTLOCK_FREE( );
ST:00000B4A|2D00 cmp r5,#0x0
ST:00000B50|FB96F010 bl 0x11280
1682| return sigs;
ST:00000B54|1C20 mov r0,r4
1683|} /* END of wait_signal */
ST:00000B56|BD70 pop {r4-r6,pc}
-000|context_switch(asm)
|
-001|wait_signal(
| ?)
|
| context_switch();
---|end of frame
# by | 2009/08/17 21:18 | RTOS팩토리(커널) | 트랙백 | 핑백(1)
... ⓗ Scheduler의 구현 ... more