달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

'OS이야기'에 해당되는 글 86

  1. 2012.01.05 O(1) 스케줄러
2012. 1. 5. 20:10

O(1) 스케줄러 OS이야기2012. 1. 5. 20:10


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
:
Posted by НooпeУ


Code Start Code End