sched.c
3413 /*
3414 * schedule() is the main scheduler function.
3415 */
3416 asmlinkage void __sched schedule(void)
3474 spin_lock_irq(&rq->lock); // 프로세스 전환시 락을 건다.
spin_lock_irq는 include/linux/spinlock.h 에서 다음과 같이 선언 되어 있다.
210 #define spin_lock_irq(lock) _spin_lock_irq(lock)
_spin_lock_irq는 kernel/spinlock.c 에 다음과 같이
100 void __lockfunc _spin_lock_irq(spinlock_t *lock)
101 {
102 local_irq_disable();
103 preempt_disable();
104 spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
105 _raw_spin_lock(lock);
106 }
array = rq->active;
3501 if (unlikely(!array->nr_active)) {
3502 /*
3503 * Switch the active and expired arrays.
3504 */
3505 schedstat_inc(rq, sched_switch);
3506 rq->active = rq->expired;
3507 rq->expired = array;
3508 array = rq->active;
3509 rq->expired_timestamp = 0;
3510 rq->best_expired_prio = MAX_PRIO;
3511 }
3512
3513 idx = sched_find_first_bit(array->bitmap);//active에서 가장 작은 수로 masking bit를 찾는다.
3514 queue = array->queue + idx;
3515 next = list_entry(queue->next, struct task_struct, run_list);
3448 rq = this_rq(); // 현재 rq의 포인터를 가져오는 매크로 함수? 아래와 같이 정의 되어있다.
293 #define this_rq() (&__get_cpu_var(runqueues))
asm-generic/percpu.h
20 #define __get_cpu_var(var) per_cpu(var, smp_processor_id())
3552 sched_info_switch(prev, next);
3553 if (likely(prev != next)) {
3554 next->timestamp = next->last_ran = now;
3555 rq->nr_switches++;
3556 rq->curr = next;
3557 ++*switch_count;
3558
3559 prepare_task_switch(rq, next);
3560 prev = context_switch(rq, prev, next); // <------
3561 barrier();
3562 /*
3563 * this_rq must be evaluated again because prev may have moved
3564 * CPUs since it called schedule(), thus the 'rq' on its stack
3565 * frame will be invalid.
3566 */
3567 finish_task_switch(this_rq(), prev);
3568 } else
3569 spin_unlock_irq(&rq->lock);
댓글 없음:
댓글 쓰기