記事ディレクトリ
1.rt_sched_class構造変数タイプsched_class
[Linuxカーネル]リアルタイムスケジューリングクラス③(リアルタイムスケジューリングクラスrt_sched_classソースコード|スケジューリングクラスsched_classソースコード)ブログでは、リアルタイムスケジューリングクラスのrt_sched_class
構造、特定のフィールドの意味の分析を開始します。構造の、
rt_sched_class
構造はlinux-5.6.18\kernel\sched\rt.c
、Linuxカーネルのソースコードのソースファイルで定義されています。
const struct sched_class rt_sched_class = {
.next = &fair_sched_class,
.enqueue_task = enqueue_task_rt,
.dequeue_task = dequeue_task_rt,
.yield_task = yield_task_rt,
.check_preempt_curr = check_preempt_curr_rt,
.pick_next_task = pick_next_task_rt,
.put_prev_task = put_prev_task_rt,
.set_next_task = set_next_task_rt,
#ifdef CONFIG_SMP
.balance = balance_rt,
.select_task_rq = select_task_rq_rt,
.set_cpus_allowed = set_cpus_allowed_common,
.rq_online = rq_online_rt,
.rq_offline = rq_offline_rt,
.task_woken = task_woken_rt,
.switched_from = switched_from_rt,
#endif
.task_tick = task_tick_rt,
.get_rr_interval = get_rr_interval_rt,
.prio_changed = prio_changed_rt,
.switched_to = switched_to_rt,
.update_curr = update_curr_rt,
#ifdef CONFIG_UCLAMP_TASK
.uclamp_enabled = 1,
#endif
};
rt_sched_class
構造体変数は、スケジューリングクラスタイプであるsched_class
構造体タイプです。構造体のフィールドと関数ポインタの意味は次のとおりです。
- [Linuxカーネル]スケジューラ②(sched_classスケジューリングクラス構造ソースコード|ソースコードパスlinux-5.6.18 \ kernel \ sched \ sched.h)
- 【Linuxカーネル】スケジューラ③(sched_classスケジューリングクラス構造解析|次のフィールド|enqueue_task関数|dequeue_task関数)
- [Linuxカーネル]スケジューラ④(sched_classスケジューリングクラス構造解析|yield_task関数|heck_preempt_curr関数|task_struct関数)
- 【Linuxカーネル】スケジューラ⑤(put_prev_task、set_next_task関数|select_task_rq関数|migrate_task_rq関数)
- [Linuxカーネル]スケジューラ✧(task_woken関数|set_cpus_allowed関数|rq_online関数|rq_offline関数)
ブログには詳細な紹介があります。
次に、次のフィールド値
Linuxシステムの「schedulingclass」リンクリストでは、次の「schedulingclass」ポインタが公正なます。
.next = &fair_sched_class,
参照: [Linuxカーネル]スケジューラ③(sched_classスケジューリングクラス構造分析|次のフィールド|enqueue_task関数|dequeue_task関数)
Linuxシステム全体に複数の 「スケジューリングクラス」があり、優先度順にソートされています。これらの「スケジューリングクラス」は「リンクリスト」に入れられ、優先度の高い「スケジューリングクラス」が先に実行され、優先度の低いものが実行されます。優先順位は後で実行されます。
sched_class
スケジューリングクラス構造のnext
フィールド、 「スケジューリングクラス」リンクリストの次の「スケジューリングクラス」を指します;(優先度はこのスケジューリングクラスよりも低くなります)
const struct sched_class *next;
ソースパス: linux-5.6.18 \ kernel \ sched \ sched.h#1709;
3、enqueue_task関数ポインター値
タスクタスク enqueue_task_rt
を「実行キュー」(赤黒木)の「テール」(右端)に格納します。
.enqueue_task = enqueue_task_rt,
enqueue_task_rt関数は次のとおりです。
static void
enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
{
struct sched_rt_entity *rt_se = &p->rt;
if (flags & ENQUEUE_WAKEUP)
rt_se->timeout = 0;
enqueue_rt_entity(rt_se, flags);
if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
enqueue_pushable_task(rq, p);
}
参照: [Linuxカーネル]スケジューラ③(sched_classスケジューリングクラス構造分析|次のフィールド|enqueue_task関数|dequeue_task関数)
sched_class
スケジューリングクラス構造のenqueue_task
関数を指しており、関数が呼び出されると、 「プロセス」を「実行キュー」に追加でき、nr_running
自動的に11ずつインクリメントされます。1 ;
- プロセスはスケジューリングエンティティです。
- 実行キューは赤黒木です。
void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
ソースコードパス: linux-5.6.18 \ kernel \ sched \ sched.h#1715;
4、dequeue_task関数ポインター値
「実行キュー」(赤黒木)の「テール」(右端)からタスクタスク を削除します。dequeue_task_rt
.dequeue_task = dequeue_task_rt,
dequeue_task_rt関数は次のとおりです。
static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags)
{
struct sched_rt_entity *rt_se = &p->rt;
update_curr_rt(rq);
dequeue_rt_entity(rt_se, flags);
dequeue_pushable_task(rq, p);
}
参照: [Linuxカーネル]スケジューラ③(sched_classスケジューリングクラス構造分析|次のフィールド|enqueue_task関数|dequeue_task関数)
dequeue_task
スケジューリングクラス構造のdequeue_task
関数を指します。この関数を呼び出すと、 「実行キュー」から「プロセス」を削除し、11ずつデクリメントできます。nr_running
1 ;
- プロセスはスケジューリングエンティティです。
- 実行キューは赤黒木です。
void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
ソースコードパス: linux-5.6.18 \ kernel \ sched \ sched.h#1716;
5、yield_task関数ポインタ値
yield_task_rt
関数ポインタが指す関数を呼び出し、積極的に実行を断念します。
.yield_task = yield_task_rt,
yield_task_rt関数は次のとおりです。
static void yield_task_rt(struct rq *rq)
{
requeue_task_rt(rq, rq->curr, 0);
}
参照: [Linuxカーネル]スケジューラ④(sched_classスケジューリングクラス構造解析|yield_task関数|heck_preempt_curr関数|task_struct関数)
sched_class
スケジューリングクラス構造のyield_task
関数を指し、関数が呼び出されると、 「プロセス」は割り当てられたCPUタイムスライスの実行許可を放棄し、最初に 「実行キュー」からプロセスをデキューし、次にそれをキューの最後に置きます。
- プロセスはスケジューリングエンティティです。
- 実行キューは赤黒木です。
つまり、この関数は、スケジューリングエンティティ(プロセス)を赤黒木(実行キュー)の右端(端)に格納するために呼び出されます。
void (*yield_task) (struct rq *rq);
ソースコードパス: linux-5.6.18 \ kernel \ sched \ sched.h#1717;
6、pick_next_task_rt関数
pick_next_task_rt
関数を呼び出して、「実行キュー」(赤黒木)でスケジュールするタスクを選択します。
.pick_next_task = pick_next_task_rt,
pick_next_task_rt関数は次のとおりです。
static struct task_struct *pick_next_task_rt(struct rq *rq)
{
struct task_struct *p;
if (!sched_rt_runnable(rq))
return NULL;
p = _pick_next_task_rt(rq);
set_next_task_rt(rq, p, true);
return p;
}
7、pick_next_task_rt関数
put_prev_task_rt
関数を呼び出して、「実行キュー」(赤黒木)で実行をスケジュールするタスクを選択します。その戻り値は、スケジュールするタスクです。
.put_prev_task = put_prev_task_rt,
put_prev_task_rt関数は次のとおりです。
static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
{
update_curr_rt(rq);
update_rt_rq_load_avg(rq_clock_pelt(rq), rq, 1);
/*
* The previous task needs to be made eligible for pushing
* if it is still active
*/
if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1)
enqueue_pushable_task(rq, p);
}