[英]Call a function from a function pointer without assigning?
通常我們必須這樣做才能從 function 指針調用 function:
int foo()
{
}
int main()
{
int (*pFoo)() = foo; // pFoo points to function foo()
foo();
return 0;
}
在Linux kernel代碼中, sched_class有很多function個指針:
struct sched_class {
const struct sched_class *next;
void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
void (*yield_task) (struct rq *rq);
bool (*yield_to_task) (struct rq *rq, struct task_struct *p, bool preempt);
.....
}
在pick_next_task function中定義了一個名為class
的sched_class
的本地實例,直接調用其中的function而不賦值給具有相同簽名的外部函數(從for_each_class
開始):
static inline struct task_struct *
pick_next_task(struct rq *rq)
{
const struct sched_class *class;
struct task_struct *p;
/*
* Optimization: we know that if all tasks are in
* the fair class we can call that function directly:
*/
if (likely(rq->nr_running == rq->cfs.h_nr_running)) {
p = fair_sched_class.pick_next_task(rq);
if (likely(p))
return p;
}
for_each_class(class) {
p = class->pick_next_task(rq);
if (p)
return p;
}
BUG(); /* the idle class will always have a runnable task */
}
是不是因為sched_class中的每一個function指針都與實際實現的sched_class
同名,所以每次通過sched_class的sched_class
指針調用時,都會自動在kernel地址空間中找到匹配的符號?
for_each_class
的定義應該為你清除它
#define for_each_class(class) \
for (class = sched_class_highest; class; class = class->next)
如果你 go 跟蹤, sched_class_highest
結束這樣的事情
#define sched_class_highest (&stop_sched_class)
extern const struct sched_class stop_sched_class;
/*
* Simple, special scheduling class for the per-CPU stop tasks:
*/
const struct sched_class stop_sched_class = {
.next = &rt_sched_class,
.enqueue_task = enqueue_task_stop,
.dequeue_task = dequeue_task_stop,
.yield_task = yield_task_stop,
.check_preempt_curr = check_preempt_curr_stop,
.pick_next_task = pick_next_task_stop,
.put_prev_task = put_prev_task_stop,
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_stop,
#endif
.set_curr_task = set_curr_task_stop,
.task_tick = task_tick_stop,
.get_rr_interval = get_rr_interval_stop,
.prio_changed = prio_changed_stop,
.switched_to = switched_to_stop,
};
現在你快樂嗎? :)
https://github.com/torvalds/linux/blob/v3.3/kernel/sched/sched.h#L850
查看for_each_class
宏的擴展。 它在使用之前將值分配給class
指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.