컨텍스트 스위치를 발생시키는 시스템 콜과 아닌 시스템콜
모든 시스템 콜이 컨텍스트 스위치를 발생시키는 것은 아니다.
하지만 컨텍스트 스위치를 유발하지 않는 시스템 콜을 떠올리려 하니 명확한 예시가 바로 생각나지 않았다. 이를 명확히 이해하기 위해, (gpt와) 리눅스 소스 코드를 분석하며 특정 시스템 콜이 컨텍스트 스위칭을 발생시키는지 여부를 확인해보았다.
컨텍스트 스위치가 일어나는 경우
우선 비교를 위해, 컨텍스트 스위치를 발생시키는 시스템 콜부터 찾아보았다.
컨텍스트 스위치가 발생하는 가장 명확하고 간단한 시스템 콜이 무엇일지 고민한 끝에, 일정 시간 동안 프로세스를 Blocking 상태로 만드는 sleep()을 선택했다.
sleep()
과 관련된 시스템 콜은 nanosleep
으로 구현되어 있다.
이를 통해 hrtimer_nanosleep
함수가 호출되는 것을 확인할 수 있었다.
그 과정에서, do_nanosleep(&t, mode);
라는 함수가 실제로 sleep 관련 로직을 수행하는 것을 알 수 있었다.
이 함수에서 다음과 같은 코드가 존재했다.
if (likely(t->task))
schedule();
대기 상태로 전환될 때 schedule()
함수가 호출되며 컨텍스트 스위칭이 발생하는 것을 확인할 수 있었다.
결론1. 시스템 콜 중 sleep은 컨텍스트 스위치가 일어날 수 있다
컨텍스트 스위치가 일어나지 않는 경우
GPT에게 물어본 결과, getpid
와 같은 시스템 콜은 컨텍스트 스위치 없이 수행된다고 했다. 이를 확인하기 위해 kernel/sys.c
파일에서 이 시스템 콜을 정의하는 매크로를 찾아보았다.
이 매크로는 task_tgid_vnr(current);
를 호출하도록 되어 있었고 이 함수의 정의는 다음과 같다.
pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
struct pid_namespace *ns)
{
pid_t nr = 0;
rcu_read_lock();
if (!ns)
ns = task_active_pid_ns(current);
nr = pid_nr_ns(rcu_dereference(*task_pid_ptr(task, type)), ns);
rcu_read_unlock();
return nr;
}
이 함수 내부에는 컨텍스트 스위치를 유발할 수 있는 코드가 존재하지 않는 것을 확인했다.
결론2. 시스템 콜 중 getpid는 컨텍스트 스위치 없이 수행된다.