<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Peter Chubb &lt;peterc@gelato.unsw.edu.au&gt;

Currently, the context switch counters reported by getrusage() are
always zero.  The appended patch adds fields to struct task_struct to
count context switches, and adds code to do the counting.

The patch adds 4 longs to struct task struct, and a single addition to
the fast path in schedule().



Add context switch counters to struct task_struct; add code to update them
in schedule(), initialise them in copy_mm(), and copy them to user space in
getrusage().



 include/linux/sched.h |    1 +
 kernel/exit.c         |    2 ++
 kernel/fork.c         |    1 +
 kernel/sched.c        |    3 ++-
 kernel/sys.c          |    6 ++++++
 5 files changed, 12 insertions(+), 1 deletion(-)

diff -puN include/linux/sched.h~rusage-context-switch-counters include/linux/sched.h
--- 25/include/linux/sched.h~rusage-context-switch-counters	2003-08-26 18:18:54.000000000 -0700
+++ 25-akpm/include/linux/sched.h	2003-08-26 18:19:47.000000000 -0700
@@ -393,6 +393,7 @@ struct task_struct {
 	struct timer_list real_timer;
 	struct list_head posix_timers; /* POSIX.1b Interval Timers */
 	unsigned long utime, stime, cutime, cstime;
+	unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */
 	u64 start_time;
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
diff -puN kernel/exit.c~rusage-context-switch-counters kernel/exit.c
--- 25/kernel/exit.c~rusage-context-switch-counters	2003-08-26 18:18:54.000000000 -0700
+++ 25-akpm/kernel/exit.c	2003-08-26 18:18:54.000000000 -0700
@@ -80,6 +80,8 @@ void release_task(struct task_struct * p
 	p-&gt;parent-&gt;cmin_flt += p-&gt;min_flt + p-&gt;cmin_flt;
 	p-&gt;parent-&gt;cmaj_flt += p-&gt;maj_flt + p-&gt;cmaj_flt;
 	p-&gt;parent-&gt;cnswap += p-&gt;nswap + p-&gt;cnswap;
+	p-&gt;parent-&gt;cnvcsw += p-&gt;nvcsw + p-&gt;cnvcsw;
+	p-&gt;parent-&gt;cnivcsw += p-&gt;nivcsw + p-&gt;cnivcsw;
 	sched_exit(p);
 	write_unlock_irq(&amp;tasklist_lock);
 	spin_unlock(&amp;p-&gt;proc_lock);
diff -puN kernel/fork.c~rusage-context-switch-counters kernel/fork.c
--- 25/kernel/fork.c~rusage-context-switch-counters	2003-08-26 18:18:54.000000000 -0700
+++ 25-akpm/kernel/fork.c	2003-08-26 18:19:43.000000000 -0700
@@ -461,6 +461,7 @@ static int copy_mm(unsigned long clone_f
 	tsk-&gt;min_flt = tsk-&gt;maj_flt = 0;
 	tsk-&gt;cmin_flt = tsk-&gt;cmaj_flt = 0;
 	tsk-&gt;nswap = tsk-&gt;cnswap = 0;
+	tsk-&gt;nvcsw = tsk-&gt;nivcsw = tsk-&gt;cnvcsw = tsk-&gt;cnivcsw = 0;
 
 	tsk-&gt;mm = NULL;
 	tsk-&gt;active_mm = NULL;
diff -puN kernel/sched.c~rusage-context-switch-counters kernel/sched.c
--- 25/kernel/sched.c~rusage-context-switch-counters	2003-08-26 18:18:54.000000000 -0700
+++ 25-akpm/kernel/sched.c	2003-08-26 18:19:47.000000000 -0700
@@ -1324,8 +1324,9 @@ need_resched:
 		}
 	default:
 		deactivate_task(prev, rq);
+		prev-&gt;nvcsw++;
 	case TASK_RUNNING:
-		;
+		prev-&gt;nivcsw++;
 	}
 pick_next_task:
 	if (unlikely(!rq-&gt;nr_running)) {
diff -puN kernel/sys.c~rusage-context-switch-counters kernel/sys.c
--- 25/kernel/sys.c~rusage-context-switch-counters	2003-08-26 18:18:54.000000000 -0700
+++ 25-akpm/kernel/sys.c	2003-08-26 18:18:54.000000000 -0700
@@ -1321,6 +1321,8 @@ int getrusage(struct task_struct *p, int
 		case RUSAGE_SELF:
 			jiffies_to_timeval(p-&gt;utime, &amp;r.ru_utime);
 			jiffies_to_timeval(p-&gt;stime, &amp;r.ru_stime);
+			r.ru_nvcsw = p-&gt;nvcsw;
+			r.ru_nivcsw = p-&gt;nivcsw;
 			r.ru_minflt = p-&gt;min_flt;
 			r.ru_majflt = p-&gt;maj_flt;
 			r.ru_nswap = p-&gt;nswap;
@@ -1328,6 +1330,8 @@ int getrusage(struct task_struct *p, int
 		case RUSAGE_CHILDREN:
 			jiffies_to_timeval(p-&gt;cutime, &amp;r.ru_utime);
 			jiffies_to_timeval(p-&gt;cstime, &amp;r.ru_stime);
+			r.ru_nvcsw = p-&gt;cnvcsw;
+			r.ru_nivcsw = p-&gt;cnivcsw;
 			r.ru_minflt = p-&gt;cmin_flt;
 			r.ru_majflt = p-&gt;cmaj_flt;
 			r.ru_nswap = p-&gt;cnswap;
@@ -1335,6 +1339,8 @@ int getrusage(struct task_struct *p, int
 		default:
 			jiffies_to_timeval(p-&gt;utime + p-&gt;cutime, &amp;r.ru_utime);
 			jiffies_to_timeval(p-&gt;stime + p-&gt;cstime, &amp;r.ru_stime);
+			r.ru_nvcsw = p-&gt;nvcsw + p-&gt;cnvcsw;
+			r.ru_nivcsw = p-&gt;nivcsw + p-&gt;cnivcsw;
 			r.ru_minflt = p-&gt;min_flt + p-&gt;cmin_flt;
 			r.ru_majflt = p-&gt;maj_flt + p-&gt;cmaj_flt;
 			r.ru_nswap = p-&gt;nswap + p-&gt;cnswap;

_
</pre></body></html>