schedule() 함수는 스케줄링에 필요한 변수들을 선언하고, 스케줄링이 가능한 상태인지 검사한 다음에 preempt_disable()함수를 호출한다. 스케줄링 중에는 커널이 선점당하면 안되므로 커널 선점을 금지
2.4는 사용자 프로세스만 빼앗을 수 있고, 커널 스레드는 빼앗을 수 없다. 하지만, 2.6은 모두 선점형 프로세스임
release_kernel_lock() : 프로세스가 가지고 있는 잠금이 이쓰면 모두 이를 해제
task_struct->lock_depth만큼 __relase_kernel_lock()을 호출해서 프로세스가 가지고 있는 모든 잠금을 해제
this_rq() 함수를 이용해서 해당 프로세서의 runqueue을 가져올 수 있다.
sched_clock() 함수는 TSC 레지스터를 읽어서, 나노초 단위로 반환. 이는 스케줄러가 수행된 시간, 프로세스 전환한 시간 등을 계산할 때 기준이 된다.
spin_lock_irq(&rq->lock) 함수를 호출해서 실행 큐에 대한 스핀 락을 얻으며, 인터럽트 요청도 금지.
task->flags멤버로 프로세스의 상태를 조사해서 실행이 종료된 프로세스로 표시되어 있으면, state 멤버를 EXIT_DEAD로 업데이트한다.
워드 프로세스와 같이 interactive한 프로세스는 실행큐에 가능한 많이 존재해야 한다. 그러므로 INTERRUPTIBLE 하다면 TASK_RUNNING상태로 유지하는 것이 바람직하다.
smp_processor_id() 매크로를 호출
실행 큐에 실행중인 프로세스가 없으면, go_idle() 레이블로 이동해서 cpu가 놀고 있을 때의 처리와 실행 큐에 실행중인 프로세스가 업을 때의 처리를 수행
실행 큐에 실행가능한 프로세스가 있다면 , switch_tasks를 호출
sched_info_switch(prev, next);
if(prev != next)
{
prepare_task_switch(rq, next);
prev= context_switch(rq, prev, next);
barrier();
finish_task_switch(this_rq(), prev);
}
sched_info_switch() 함수는 prev, next의 스케줄러 관련 통계 정보를 업데이트한다.
통계정보 업데이트는 sched_info_depart() 함수에서 처리한다.
234static inline void sched_info_depart(struct task_struct *t) 235{ 236 unsigned long long delta = task_rq(t)->clock - 237 t->sched_info.last_arrival; 238 239 t->sched_info.cpu_time += delta; 240 rq_sched_info_depart(task_rq(t), delta); 241 242 if (t->state == TASK_RUNNING) 243 sched_info_queued(t); 244} 245
prepare_task_switch() 함수는 프로세스 전환을 위한 준비작업을 수행.
- 프로세스 전환하는 동안은 변경이 있어서는 안되니, 각종 잠금을 수행하는 작업을 수행
- prepare_task_swtich() 함수는 반드시 finish_task_switch() 함수와 짝을 이뤄야한다.
- 프로세스 전환을 위해 획득했던 자원을 해제하는 역할을 하는 함수가 finish_task_switch() 함수이다.
- context_switch()는 프로세스의 메모리 관리 부분과 레지스터 값을 교환하는 것을 처리한다.
- 커널 2.4에 있던 switch_mm(), switch_to()함수가 여기서 호출된다.
runquque에 실행가능한 프로세스가 없다면?
- 다른 프로세서의 runqueue에서 가져온다.
- 아니면 idle 프로세스를 수행시킨다. (swapper process라고도 함)
다른 프로세서로부터 일감을 나눠받기 위해 idle_balance(cpu, rq)
cpu : 일감을 가져올 cpu번호
rq : 해당 cpu에서 사용하는 실행큐
일감을 나눠받는다. 그 일을 한다. 만약 다른 프로세서에도 일감이 없다면? prio_array_t *active, *expire의 큐를 바꿔서 실행한다.
즉, 다른 프로세서에서도 일감이 없다면 큐를 바꿈으로써 실행큐에 새로운 프로세스들을 넣는 것.
'OS이야기' 카테고리의 다른 글
슈퍼블록과 마운트 (0) | 2012.01.05 |
---|---|
프로세스 종료 (0) | 2012.01.04 |
프로세스 생성 (2.4) (0) | 2012.01.04 |
프로세스 관리 - execv() fork() (0) | 2012.01.04 |
프로세스 관리 - 파일시스템 & 파일 (0) | 2012.01.04 |