본문 바로가기

Linux(Centos or RHEL)/RHEL 기초

프로세스를 TASK_RUNNING(CPU 실행) 상태로 바꾸는 함수...?

프로세스를 TASK_UNINTERRUPTIBLETASK_RUNNING(CPU 실행) 상태로 바꿀 때 호출되는 함수들에 대해서 공부를 해 보았습니다.

커널 버전은 v2.6.39.4 입니다.

http://rousalome.egloos.com/10003491

 

[리눅스커널] 스케줄링: TASK_RUNNING(CPU 실행)로 바뀔 때 호출되는 함수

TASK_RUNNING(CPU실행)로 바뀔 때 호출하는 함수 분석 프로세스 상태를 CPU실행(TASK_RUNNING)으로 변경하는 함수는 1개 밖에 없습니다. __schedule() 함수를 실행할 때 프로세스는 CPU를 점유하면서 실행하는 상태로 바뀝니다. __schedule() 함수 코드를 살펴봅시다. [https://elixir.bootlin.com/

rousalome.egloos.com

 

프로세스의 상태를 TASK_RUNNING(CPU 실행)로 바꾸는 함수는 1개 밖에 없습니다.

(1) schedule()

 

이 함수가 실행되면 프로세스는 CPU를 점유하면서 CPU 실행 상태로 바뀌게 됩니다.

 

[https://elixir.bootlin.com/linux/v2.6.39.4/source/kernel/sched.c#L4071]

(1) schedule()

아래의 코드 중 “if (likely(prev != next))” 부분이 컨텍스트 스위칭을 통하여 다음에 실행할 프로세스의 정보(task_struct)CPU가 현재 실행 중인 프로세스의 주소를 나타내는 “curr“에 매핑 시킵니다. 이를 통하여 프로세스를 TASK_RUNNING(CPU 실행) 상태로 바꾸는 것입니다.

/*

* schedule() is the main scheduler function.

*/

asmlinkage void __sched schedule(void)

{

struct task_struct *prev, *next;

unsigned long *switch_count;

struct rq *rq;

int cpu;

...

 

if (likely(prev != next)) {

rq->nr_switches++;

rq->curr = next;

++*switch_count;

 

context_switch(rq, prev, next); /* unlocks the rq */

/*

* The context switch have flipped the stack from under us

* and restored the local variables which were saved when

* this task called schedule() in the past. prev == current

* is still correct, but it can be moved to another cpu/rq.

*/

cpu = smp_processor_id();

rq = cpu_rq(cpu);

}

 

 

[https://elixir.bootlin.com/linux/v2.6.39.4/source/kernel/sched.c#L440]

rq 구조체는 다음과 같이 정의되어 있습니다. 아래와 같이 ”curr“변수는 task_struct의 주소를 저장하는 변수인 것을 알 수 있습니다.

 

/*

* This is the main, per-CPU runqueue data structure.

*

* Locking rule: those places that want to lock multiple runqueues

* (such as the load balancing or the thread migration code), lock

* acquire operations must be ordered by ascending &runqueue.

*/

struct rq {

/* runqueue lock: */

raw_spinlock_t lock;

...

/*

* This is part of a global counter where only the total sum

* over all CPUs matters. A task can increase this counter on

* one CPU and if it got migrated afterwards it may decrease

* it on another CPU. Always updated under the runqueue lock:

*/

unsigned long nr_uninterruptible;

 

struct task_struct *curr, *idle, *stop;

unsigned long next_balance;

struct mm_struct *prev_mm;

'Linux(Centos or RHEL) > RHEL 기초' 카테고리의 다른 글

인터럽트 핸들러?  (0) 2020.04.23
인터럽트?  (0) 2020.04.23
linux에서 likely와 unlikely란?  (0) 2020.04.22
sleep과 wait의 차이?  (0) 2020.04.22
프로세스를 TASK_UNINTERRUPTIBLE 상태로 바꾸는 함수...?  (0) 2020.04.22