O int 0x80
assume i386; outras arquiteturas podem usar outras coisas por exemplo syscall
em amd64 . Se a comutação de contexto acontece toda vez que uma chamada de sistema é feita, isso deve ser prontamente visível se nós rodarmos um programa que gera números estupidamente grandes de chamadas de sistema. Felizmente, tenho apenas esse programa disponível.
bits 64
section .text
global _start
_start: mov r9,9551615
mov rax,1 ; sys_write
mov rdi,1 ; stdout
mov rsi,letter
mov rdx,1 ; length
_again: syscall
dec r9
jnz _again
mov rax,60 ; sys_exit
mov rdi,0 ; exit code
syscall
section .data
letter: db "a"
Quando compilamos isso em um sistema Linux de 64 bits e o executamos em perf
, observamos
$ nasm -f elf64 -g -F dwarf -o max.o max.asm
$ ld -o max max.o
$ sudo perf stat ./max > /dev/null 2> perf.log
$ grep context perf.log
88 context-switches # 0.051 K/sec
$
apenas 88 switches de contexto para esse processo; se houvesse uma mudança de contexto toda vez que o kernel estivesse no contexto do processo, deveríamos ter visto algum lugar mais próximo das chaves de contexto 9551615.
Agora! Se você quiser ver o sistema se debatendo com as opções de contexto, execute as etapas acima em strace
$ strace -c ./max
...
E em outra janela temos vmstat 1
em execução ...
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 896 333928 2132 3124628 0 0 0 0 74 98 0 0 100 0 0
0 0 896 333896 2132 3124628 0 0 0 0 89 103 0 0 100 0 0
0 0 896 333896 2132 3124628 0 0 0 0 65 85 0 0 100 0 0
0 0 896 333896 2132 3124628 0 0 0 0 67 83 0 0 100 0 0
2 0 896 333756 2132 3124628 0 0 0 0 21460 529902 10 29 61 0 0
3 0 896 333832 2132 3124628 0 0 0 0 23690 652506 13 32 55 0 0
1 0 896 333832 2132 3124628 0 0 0 0 27574 673152 11 33 55 0 0
0 0 896 333768 2132 3124628 0 0 0 0 24351 650723 11 30 59 0 0
Parece bastante evidente quando strace
e max
(e outros softwares, se você esqueceu de /dev/null
da saída) começarem a ser alternados entre.