上下文切换进程

我必须做一个系统调用来计算一个过程的自愿和非自愿的上下文切换。 我已经知道添加一个新的系统调用到Linux内核的步骤,但我不知道从哪里开始进行上下文切换function。 任何想法?

谢谢。

Solutions Collecting From Web of "上下文切换进程"

如果您的系统调用只应报告统计信息,则可以使用内核中已有的上下文切换计数代码。

wait3系统调用或getrusage系统调用已经在struct rusage字段中报告上下文切换计数:

 struct rusage { ... long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ }; 

您可以通过运行来尝试:

 $ /usr/bin/time -v /bin/ls -R .... Voluntary context switches: 1669 Involuntary context switches: 207 

其中“ /bin/ls -R ”是任何程序。

通过在内核源代码中搜索一个“struct rusage”,你可以在kernel / sys.c中找到这个accumulate_thread_rusage ,它更新了rusage结构。 它从struct task_struct *t读取; 字段t->nvcsw;t->nivcsw;

 1477 static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r) 1478 { 1479 r->ru_nvcsw += t->nvcsw; // <<=== here 1480 r->ru_nivcsw += t->nivcsw; 1481 r->ru_minflt += t->min_flt; 1482 r->ru_majflt += t->maj_flt; 

那么你应该在内核文件夹中搜索nvcswnivcsw来查找它们是如何被内核更新的。

asmlinkage void __sched schedule(void) :

 4124 if (likely(prev != next)) { // <= if we are switching between different tasks 4125 sched_info_switch(prev, next); 4126 perf_event_task_sched_out(prev, next); 4127 4128 rq->nr_switches++; 4129 rq->curr = next; 4130 ++*switch_count; // <= increment nvcsw or nivcsw via pointer 4131 4132 context_switch(rq, prev, next); /* unlocks the rq */ 

指针switch_count来自同一个文件的第4091行或第4111行 。

PS:从超现实的链接是伟大的: http : //oreilly.com/catalog/linuxkernel/chapter/ch10.html (搜索context_swtch

这已经存在:虚拟文件/proc/NNNN/status (其中NNNN是您想知道的进程的十进制进程ID)包含自愿和非自愿上下文切换的计数。 与getrusage不同,这允许您学习任何进程的上下文切换计数,而不仅仅是儿童。 有关更多详细信息,请参阅proc(5)页 。

一个进程会在发生阻塞,时间到期或中断等情况下进行上下文切换。最后调用schedule()函数。 既然你想为每个进程单独计数,你必须为每个进程保留一个新的变量来计算上下文切换的数量。 而且你可以每次在当前进程的时间表中更新这个变量。 使用你的系统调用你可以读取这个值。 这是pintos的日程安排功能的片段,

 static void schedule (void) { struct thread *cur = running_thread (); struct thread *next = next_thread_to_run (); struct thread *prev = NULL; ASSERT (intr_get_level () == INTR_OFF); ASSERT (cur->status != THREAD_RUNNING); ASSERT (is_thread (next));<br/> if (cur != next) prev = switch_threads (cur, next); <== here you can update count of "cur" thread_schedule_tail (prev); } 

上下文切换的总数

cat /proc/PID/sched|grep nr_switches

自愿的上下文切换

cat /proc/PID/sched | grep nr_voluntary_switches

非自愿的上下文切换

cat /proc/PID/sched|grep nr_involuntary_switches

其中PID是您希望监视的进程的进程ID。

但是,如果你想通过修补(创建一个钩子)linux源来获得这些统计信息,那么与调度相关的代码就出现在了

核心/排程/

源代码树的文件夹。 尤其是

kernel / sched / core.c包含schedule()函数,它是linux调度器的代码。 CFS(完全公平的调度程序)的代码是目前Linux中的几个调度程序之一,也是最常用的代码。

/kernel/sched/fair.c

当TIF_NEED_RESCHED标志被设置时,scheduler()被执行,所以找出这个标志被设置的所有地方(在linux源代码上使用cscope),这将使你深入了解一个进程发生的上下文切换的类型。