编写系统调用来计算进程的上下文切换

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写系统调用来计算进程的上下文切换相关的知识,希望对你有一定的参考价值。

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

答案

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

wait3 syscallgetrusage 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;

然后你应该在kernel文件夹中搜索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来自同一档案的line 4091line 4111

PS:来自perreal的链接很棒:http://oreilly.com/catalog/linuxkernel/chapter/ch10.html(搜索context_swtch

另一答案

这已经存在:虚拟文件/proc/NNNN/status(其中NNNN是您想要了解的进程的十进制进程ID)除其他外,包含自愿和非自愿上下文切换的计数。与getrusage不同,这允许您了解任何过程的上下文切换计数,而不仅仅是孩子。有关详细信息,请参阅proc(5) manpage

另一答案

在阻塞,时间量程到期或中断等情况下,进程将进行上下文切换。最终调用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/刹车灯/fair.从

如果设置了TIF_NEED_RESCHED标志,则执行scheduler(),因此找出该标志所在的所有位置(在linux源代码上使用cscope),这将使您深入了解进程发生的上下文切换类型。

以上是关于编写系统调用来计算进程的上下文切换的主要内容,如果未能解决你的问题,请参考以下文章

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

Lab3:结合中断上下文切换和进程上下文切换分析Linux内核一般执行过程

结合中断上下文切换和进程上下文切换分析Linux内核一般执行过程

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程