Linux System Calls' Forum, #7:(第157號系統服務)sys_sched_getscheduler

jollen 發表於 November 5, 2006 12:03 AM

「作業系統的排程器(scheduler)提供好幾種排程演算法,並在不同的應用場合,或是不同的 process 採取適合的排程策略(policy)。」

Linux 的 process descriptor 資料結構為 struct task_struct,我們最早開始談論與 process 有關的 system call 時,就看過這個用來描述 process 的資料結構。struct task_struct 裡頭的 policy 欄位便是用來描述該 process 的排程策略。

與排程有關的系統呼叫

整理與 scheduling 有關的幾個 system call 如下(可參考「Linux 2.6 的 System Call:12 大類」),另外 Jollen 也把到目前為止已介紹過的 system call 加上紅色註記。

號碼 System Call 名稱 Manipulation

34

sys_nice 關於 struct task_struct->nice 欄位。

154

sys_sched_setparam 關於 struct task_struct->rt_priority 欄位。

155

sys_sched_getparam 關於 struct task_struct->rt_priority 欄位。

156

sys_sched_setscheduler 關於 struct task_struct->policy 欄位。(這是下一個要讀的)

157

sys_sched_getscheduler 關於 struct task_struct->policy 欄位。

158

sys_sched_yield 暫不討論。

159

sys_sched_get_priority_max 根據 'policy' 傳回 'rt_priority' 所允許的最大 priority 值。

160

sys_sched_get_priority_min 根據 'policy' 傳回 'rt_priority' 所允許的最小 priority 值。

161

sys_sched_rr_get_interval 若 policy 為 SCHED_RR(Round Robin policy),則傳回 time quantum(time slice)值。

241

sys_sched_setaffinity 這是 Linux 2.6 新增加的 system call。

242

sys_sched_getaffinity 這是 Linux 2.6 新增加的 system call。

「'sys_sched_getscheduler' 便是用來取得 process 排程策略(policy)的 system call。」

「'struct task_struct->policy' 是今天要了解的主題。」

我們想要思考一個問題「作業系統的教科書提到的排程演算法中,Round Robin 是我們知道現在的分時作業系統(eg. Linux)所採用的策略,所以我想了解 Linux 的 process descriptor 裡,是哪一個 field 在紀錄這件事情。」

struct task_struct 的 policy 欄位

這個問題還挺簡單的,因為直接看 struct task_struct 幾乎就能猜到是哪一個 field,再用谷歌找資料來印證我們的設假;另外,看「Understanding the Linux Kernel」也寫的很清楚。

struct task_struct {
	...
	unsigned long policy;
	...
};

接著再回頭來看今天的主題,sys_sched_getscheduler 的實作(Linux 2.6.11+):

/**
 * sys_sched_getscheduler - get the policy (scheduling class) of a thread
 * @pid: the pid in question.
 */
asmlinkage long sys_sched_getscheduler(pid_t pid)
{
	int retval = -EINVAL;
	task_t *p;  // jollen: 'typedef struct task_struct task_t;'

	if (pid < 0)
		goto out_nounlock;

	retval = -ESRCH;
	read_lock(&tasklist_lock);
	p = find_process_by_pid(pid); // 參照說明 1.
	if (p) {
		retval = security_task_getscheduler(p);
		if (!retval)
			retval = p->policy; // 參照說明 2.
	}
	read_unlock(&tasklist_lock);

out_nounlock:
	return retval;
}

取出重點部位來看:

  1. 取得指定 PID 的 process descriptor。常常在一些說明文件看到「若 PID 為 0,則取得 current 的...」,不過這裡的實作好像看的不太清楚,沒關係等一下再來往下看 code。
  2. 傳回 policy 欄位。

很簡單的將 sys_sched_getscheduler 看了一下,並且了解到 policy 欄位的用途。

find_process_by_pid

把 find_process_by_pid() 的實作拿出來看:

/**
 * find_process_by_pid - find a process with a matching PID value.
 * @pid: the pid in question.
 */
static inline task_t *find_process_by_pid(pid_t pid)
{
	return pid ? find_task_by_pid(pid) : current;
}

發現一件很重要的是,也是之前都沒提過的。

「若 PID 為 0,則傳回 current,否則傳回 PID 為 pid 的 process 之 process descriptor。」

別忘了,current 的 data type 也是 'struct task_struct'。

Linux 排程策略:policy 欄位的值

Linux 2.6 提供的排程策略如下:

/*
 * Scheduling policies
 */
#define SCHED_NORMAL		0
#define SCHED_FIFO			1
#define SCHED_RR			2
#define SCHED_BATCH		3

定義在 include/linux/sched.h。順帶把 Linux 2.4 提供的排程策略也節錄一下:

/*
 * Scheduling policies
 */
#define SCHED_OTHER		0
#define SCHED_FIFO			1
#define SCHED_RR			2

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw