【Linuxカーネル】リアルタイムスケジューリングクラス⑤(リアルタイムスケジューリングクラスrt_sched_classソース分析|構造体フィールドと関数ポインタ分析)





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システムの「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_running1 ;

  • プロセスはスケジューリングエンティティです。
  • 実行キューは赤黒木です。
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);
}

おすすめ

転載: blog.csdn.net/han1202012/article/details/123883125