我必须做一个系统调用来计算自愿和&过程的非自愿上下文切换。我已经知道向Linux内核添加新系统调用的步骤,但我不知道我应该从哪里开始上下文切换功能。有什么想法吗?
答案 0 :(得分:9)
如果您的系统调用只应报告统计信息,则可以使用内核中已有的上下文切换计数代码。
wait3 syscall或getrusage syscall已在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中找到更新rusage结构的this accumulate_thread_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;
然后你应该在内核文件夹中搜索nvcsw
和nivcsw
来查找内核如何更新它们。
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
来自同一文件的line 4091或line 4111。
PS:来自perreal的链接很棒:http://oreilly.com/catalog/linuxkernel/chapter/ch10.html(搜索context_swtch
)
答案 1 :(得分:5)
这已经存在:虚拟文件/proc/NNNN/status
(其中NNNN是您想要了解的进程的十进制进程ID)除其他外,还包含自愿和非自愿上下文切换的计数。与getrusage
不同,这允许您了解任何进程的上下文切换计数,而不仅仅是子进程。有关详细信息,请参阅proc(5)
manpage。
答案 2 :(得分:0)
进程将在阻塞,时间量程到期或中断等情况下进行上下文切换。最后调用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);
}
答案 3 :(得分:0)
上下文切换总数
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源来获取这些统计信息,那么与调度相关的代码就会出现在
中内核/ SCHED /
源树的文件夹。 特别是
kernel / sched / core.c包含schedule()函数,它是linux调度程序的代码。 CFS(完全公平的调度程序)的代码,它是Linux中存在的几个调度程序之一,并且最常用于
/kernel/sched/fair.c
如果设置了TIF_NEED_RESCHED标志,则执行scheduler(),因此找出此标志所在的所有位置(在linux源代码上使用cscope),这将使您深入了解发生的上下文切换类型。过程