Ecrire un appel système pour compter les changements de contexte d’un processus

Je dois faire un appel système pour compter les changements de contexte volontaires et involontaires d’un processus. Je connais déjà les étapes à suivre pour append un nouvel appel système à un kernel Linux, mais je ne sais pas où commencer pour la fonction de changement de contexte. Une idée?

Si votre appel système ne doit signaler que des statistiques, vous pouvez utiliser un code de comptage de changement de contexte qui se trouve déjà dans le kernel.

wait3 syscall ou getrusage syscall rapporte déjà le nombre de changements de contexte dans les champs de struct rusage :

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

Vous pouvez l’essayer en exécutant:

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

où ” /bin/ls -R ” est un programme quelconque.

En recherchant un “struct rusage” dans les sources du kernel, vous pouvez trouver ceci accumulate_thread_rusage dans kernel / sys.c, qui met à jour la structure de rusage. Il lit à partir de struct task_struct *t ; les champs t->nvcsw; et 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; 

Ensuite, vous devez rechercher nvcsw et nivcsw dans le dossier du kernel pour savoir comment ils sont mis à jour par le kernel.

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 */ 

Le pointeur switch_count provient de la ligne 4091 ou de la ligne 4111 du même fichier.

PS: le lien de perreal est génial: http://oreilly.com/catalog/linuxkernel/chapter/ch10.html (recherche context_swtch )

Cela existe déjà: le fichier virtuel /proc/NNNN/status (où NNNN est l’ID de processus décimal du processus que vous voulez connaître) contient, entre autres choses, le nombre de changements de contexte volontaires et involontaires. Contrairement à getrusage cela vous permet d’apprendre que le changement de contexte compte pour n’importe quel processus, pas seulement pour les enfants. Voir la page de manuel de proc(5) pour plus de détails.

Un processus crée un changement de contexte en cas de blocage, d’expiration du quantum temporel ou d’interruption, etc. Finalement, la fonction schedule () est appelée. Puisque vous voulez le compter pour chaque processus séparément, vous devez conserver une nouvelle variable pour chaque processus afin de compter le nombre de changements de contexte. Et vous pouvez mettre à jour cette variable à chaque fois en fonction du planning pour le processus en cours. En utilisant votre appel système, vous pouvez lire cette valeur. Voici un extrait de la fonction de planification de 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));
if (cur != next) prev = switch_threads (cur, next); <== here you can update count of "cur" thread_schedule_tail (prev); }

Nombre total de changements de contexte

cat /proc/PID/sched|grep nr_switches

Changements de contexte volontaires

cat /proc/PID/sched | grep nr_voluntary_switches

Changements de contexte involontaires

cat /proc/PID/sched|grep nr_involuntary_switches

où PID est l’identifiant du processus que vous souhaitez surveiller.

Cependant, si vous souhaitez obtenir ces statistiques en corrigeant (en créant un hook) une source Linux, le code associé à la planification est présent dans

kernel / sched /

dossier de l’arborescence source. En particulier

kernel / sched / core.c contient la fonction schedule (), qui est le code du planificateur linux. Le code de CFS (Scheduler Full Fair), qui est l’un des nombreux ordonnanceurs présents dans Linux et le plus couramment utilisé, est présent dans

/kernel/sched/fair.c

scheduler () est exécuté à chaque fois que le drapeau TIF_NEED_RESCHED est défini. Vous devez donc savoir à partir de quel endroit cet indicateur est défini (utilisez cscope sur le source Linux).