このページを編集する際は、編集に関する方針に従ってください。

概要

  • linux2.6/kernel/sched.cにて定義
  • 引数で渡されたプロセスIDに対応するタスクに、スケジューラポリシー、スケジューラ優先度を設定する

引数

  • pid--プロセスID
  • policy--スケジューラポリシー
    スケジューリングポリシー
    SCHED_NORMAL0
    SCHED_FIFO1
    SCHED_RR2
  • param--スケジューラの優先度

実装

/*

* setscheduler - change the scheduling policy and/or RT priority of a thread.
*/

static int setscheduler(pid_t pid, int policy, struct sched_param __user *param) {

	struct sched_param lp;
	int retval = -EINVAL;
	int oldprio, oldpolicy = -1;
	prio_array_t *array;
	unsigned long flags;
	runqueue_t *rq;
  • ランキュー(activeキューとexpiredキューの組。CPUごとに用意される。)
	task_t *p;
	if (!param || pid < 0)
		goto out_nounlock;
	retval = -EFAULT;
	if (copy_from_user(&lp, param, sizeof(struct sched_param)))
		goto out_nounlock;
  • param(ユーザ空間)からlp(カーネル空間)へコピーを行う
    • ただし、指定されたユーザアドレスが不正なアドレスである場合は、カーネルアドレスにはコピーされず、カーネルアドレスのコピー領域には0で埋められる
    • コピーできなかったサイズ(単位はbyte)を返す。正常にコピーできた場合は0を返す。
    • 詳細はcopy_from_user()/linux2.6を参照
	/*
	 * We play safe to avoid deadlocks.
	 */
	read_lock_irq(&tasklist_lock);
  • 割り込みを禁止し、読み込み/書き込み用ロックtasklist_lockを取得する
	p = find_process_by_pid(pid);
  • プロセスID pidに対応するタスクを返す
    • プロセスIDがNULLならカレントプロセスを返す
      • タスクが見つからない場合はNULLを返す
    • 詳細はfind_process_by_pid()/linux2.6を参照
	retval = -ESRCH;
	if (!p)
		goto out_unlock;

recheck:

	/* double check policy once rq lock held */
	if (policy < 0)
		policy = oldpolicy = p->policy;
	else {
		retval = -EINVAL;
		if (policy != SCHED_FIFO && policy != SCHED_RR &&
				policy != SCHED_NORMAL)
			goto out_unlock;
	}
	/*
	 * Valid priorities for SCHED_FIFO and SCHED_RR are
	 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
	 */
	retval = -EINVAL;
	if (lp.sched_priority < 0 || lp.sched_priority > MAX_USER_RT_PRIO-1)
		goto out_unlock;
	if ((policy == SCHED_NORMAL) != (lp.sched_priority == 0))
		goto out_unlock;
	retval = -EPERM;
	if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
	    !capable(CAP_SYS_NICE))
		goto out_unlock;
  • ケーパビリティがカレントタスクで設定されている場合は1を返す
  • CAP_SYS_NICEはnice()とsetpriority()システムコール利用制限を外す、またリアルタイムプロセスの生成を可能とすることを意味する
	if ((current->euid != p->euid) && (current->euid != p->uid) &&
	    !capable(CAP_SYS_NICE))
		goto out_unlock;
  • ケーパビリティがカレントタスクで設定されている場合は1を返す
  • CAP_SYS_NICEはnice()とsetpriority()システムコール利用制限を外す、またリアルタイムプロセスの生成を可能とすることを意味する
	retval = security_task_setscheduler(p, policy, &lp);
    • 詳細はsecurity_task_setscheduler()/linux2.6?を参照
	if (retval)
		goto out_unlock;
	/*
	 * To be able to change p->policy safely, the apropriate
	 * runqueue lock must be held.
	 */
	rq = task_rq_lock(p, &flags);
  • タスクpにマッピングされたCPUのランキューのロックを取得する
	/* recheck policy now with rq lock held */
	if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) {
		policy = oldpolicy = -1;
		task_rq_unlock(rq, &flags);
  • ランキューrqのロックをアンロックし、可能であればプリエンプションする
		goto recheck;
	}
	array = p->array;
	if (array)
		deactivate_task(p, task_rq(p));
  • タスクpがマッピングされている、CPUのランキューを返す
  • アクティブではないタスクpをランキューtask_rq(p)から取り除く
	retval = 0;
	oldprio = p->prio;
	__setscheduler(p, policy, lp.sched_priority);
  • タスクpに、スケジューラポリシーpolicy、スケジューラ優先度lp.sched_priorityを設定する
	if (array) {
		__activate_task(p, task_rq(p));
		/*
		 * Reschedule if we are currently running on this runqueue and
		 * our priority decreased, or if we are not currently running on
		 * this runqueue and our priority is higher than the current's
		 */
		if (task_running(rq, p)) {
  • ランキューrqにおいてタスクpが現在実行中であるか調べる
			if (p->prio > oldprio)
				resched_task(rq->curr);
  • ローカルAPICのフラグを調査&設定し、必要であればタスクrq->currのCPUに対してプロセッサ間通信(IPI)を行い再スケジュールを要求する
		} else if (TASK_PREEMPTS_CURR(p, rq))
			resched_task(rq->curr);
  • タスクpの優先度が、ランキューrqのカレントタスクの優先度より高い場合、1を返す。低い場合は0を返す。
  • ローカルAPICのフラグを調査&設定し、必要であればタスクrq->currのCPUに対してプロセッサ間通信(IPI)を行い再スケジュールを要求する
	}
	task_rq_unlock(rq, &flags);
  • ランキューrqのロックをアンロックし、可能であればプリエンプションする

out_unlock:

	read_unlock_irq(&tasklist_lock);

out_nounlock:

	return retval;

}

呼出元


履歴

  • 作者:ひら
  • 日付:2007/1/31
  • 対象:2.6.10
    更新日更新者更新内容

コメント/タグ?



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-11-24 (火) 07:18:22 (3129d)