O provedor profile fornece testes associados a um acionamento de interrupção baseado no tempo sempre fixo, intervalo de tempo especificado. Estes testes não-ancorados que não estão associados a qualquer ponto de execução específico, mas ao evento de interrupção assíncrono. Estes testes podem ser usados para fazer amostragem de alguns aspectos do estado do sistema periodicamente e as amostras podem ser usadas para deduzir o comportamento do sistema. Se a taxa de amostragem for alta, ou o tempo de amostragem for longo, uma dedução correta será possível. Através de ações do DTrace, o provedor profile pode ser usado para fazer amostragem de praticamente tudo no sistema. Por exemplo, você poderia fazer amostragem do estado do segmento atual, o estado da CPU, ou a instrução da máquina atual.
As variáveis de segmento locais não estão acessíveis para testes a partir do provedor profile . O uso do identificador especial self para fazer referência a uma variável de segmento local com tal teste não produzirá nenhuma saída.
Um teste profile- n é acionado a cada intervalo fixo em cada CPU no nível de interrupção alto. O intervalo de acionamento do teste é indicado pelo valor n: a origem da interrupção será acionada n vezes por segundo. n também pode ter um sufixo de tempo opcional, em cujo caso n é interpretado em unidades indicadas pelo sufixo. Os sufixos válidos e as unidades que eles indicam estão listados na Tabela 19–1.
Tabela 19–1 Sufixos de tempo válidos
Sufixo |
Unidades de tempo |
---|---|
nsec ou ns |
nanossegundos |
usec ou us |
microssegundos |
msec ou ms |
milissegundos |
sec ou s |
segundos |
min ou m |
minutos |
hour ou h |
horas |
day ou d |
dias |
hz |
hertz (freqüência por segundo) |
O exemplo seguinte cria um teste a ser acionado a 97 hertz para fazer amostragem do processo que está em execução no momento:
#pragma D option quiet profile-97 /pid != 0/ { @proc[pid, execname] = count(); } END { printf("%-8s %-40s %s\n", "PID", "CMD", "COUNT"); printa("%-8d %-40s %@d\n", @proc); }
Executar o exemplo acima por um breve período de tempo resulta em uma saída semelhante ao exemplo seguinte:
# dtrace -s ./prof.d ^C PID CMD COUNT 223887 sh 1 100360 httpd 1 100409 mibiisa 1 223887 uname 1 218848 sh 2 218984 adeptedit 2 100224 nscd 3 3 fsflush 4 2 pageout 6 100372 java 7 115279 xterm 7 100460 Xsun 7 100475 perfbar 9 223888 prstat 15 |
Você também usa o provedor profile-n para fazer amostragem de informações sobre o processo em execução. O script de D de exemplo seguinte usa um teste profile de 1.001 hertz para fazer amostragem da prioridade atual de um processo especificado:
profile-1001 /pid == $1/ { @proc[execname] = lquantize(curlwpsinfo->pr_pri, 0, 100, 10); }
Para ver este script de exemplo em ação, digite os seguintes comandos em uma janela:
$ echo $$ 12345 $ while true ; do let i=0 ; done |
Em outra janela, execute o script de D por um breve período de tempo, substituindo 12345 pelo PID que o comando echo retornou:
# dtrace -s ./profpri.d 12345 dtrace: script './profpri.d' matched 1 probe ^C ksh value ------------- Distribution ------------- count < 0 | 0 0 |@@@@@@@@@@@@@@@@@@@@@ 7443 10 |@@@@@@ 2235 20 |@@@@ 1679 30 |@@@ 1119 40 |@ 560 50 |@ 554 60 | 0 |
Esta saída mostra a diferença da classe de programação de compartilhamento de tempo. Como o processo do shell está girando na CPU, sua prioridade está constantemente sendo baixada pelo sistema. Se o processo do shell estivesse sendo executado menos freqüentemente, sua prioridade seria mais alta. Para ver este resultado, digite Control-C no shell que está girando e execute o script novamente:
# dtrace -s ./profpri.d 494621 dtrace: script './profpri.d' matched 1 probe |
Agora no shell, digite alguns caracteres. Quando você terminar o script do DTrace, uma saída parecida com o exemplo seguinte aparecerá:
ksh value ------------- Distribution ------------- count 40 | 0 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14 60 | 0 |
Como o processo do shell estava inativo, esperando a entrada do usuário em vez de girando na CPU, quando ele foi executado, sua prioridade era muito mais alta.
Assim como os testes profile- n, os testes tick- n são acionados a cada intervalo fixo em um nível de interrupção alto. Entretanto, ao contrário dos testes profile-n, que são acionados em cada CPU, os testes tick-n são acionados somente em uma CPU por intervalo. A CPU real pode mudar com o tempo. Como acontece com os testes profile- n, n é padronizado como taxa por segundo, mas também pode ter um sufixo de tempo opcional. Os testes tick- n têm vários usos, tais como fornecer alguma saída periódica ou tomar uma ação periódica.
Os argumentos dos testes profile são os seguintes:
arg0 |
O contador do programa (PC) no kernel na hora em que o teste foi acionado, ou 0 se o processo atual não estava sendo executado no kernel na hora em que o teste foi acionado |
arg1 |
O PC no processo no nível do usuário na hora em que o teste foi acionado, ou 0 se o processo atual estava sendo executado no kernel na hora em que o teste foi acionado |
Conforme as descrições sugerem, se arg0 for diferente de zero, então arg1 é zero; se arg0 for zero, então arg1 é diferente de zero. Portanto, você pode usar arg0 e arg1 para diferenciar o nível do usuário do nível do kernel, como neste exemplo simples:
profile-1ms { @ticks[arg0 ? "kernel" : "user"] = count(); }
O provedor profile usa temporizadores de intervalo de resolução arbitrário no sistema operacional. Em arquiteturas que não aceitam interrupções baseadas em tempo de resolução realmente arbitrário, a freqüência é limitada pela freqüência do relógio do sistema, que é especificada pela variável do kernel hz. Os testes de freqüência mais alta que hz em tais arquiteturas serão acionados algumas vezes a cada 1/ hz segundos. Por exemplo, um teste profile de 1000 hertz em uma arquitetura como tal com hz definido como 100 será acionado dez vezes em sucessão rápida a cada dez milessegundos. Em plataformas que aceitam resolução arbitrária, um teste profile de 1000 hertz seria acionado exatamente a cada um milissegundo.
O exemplo seguinte testa uma determinada resolução de arquitetura:
profile-5000 { /* * We divide by 1,000,000 to convert nanoseconds to milliseconds, and * then we take the value mod 10 to get the current millisecond within * a 10 millisecond window. On platforms that do not support truly * arbitrary resolution profile probes, all of the profile-5000 probes * will fire on roughly the same millisecond. On platforms that * support a truly arbitrary resolution, the probe firings will be * evenly distributed across the milliseconds. */ @ms = lquantize((timestamp / 1000000) % 10, 0, 10, 1); } tick-1sec /i++ >= 10/ { exit(0); }
Em uma arquitetura que aceita testes profile de resolução arbitrária, executar o script de exemplo produzirá uma distribuição uniforme:
# dtrace -s ./restest.d dtrace: script './restest.d' matched 2 probes CPU ID FUNCTION:NAME 0 33631 :tick-1sec value ------------- Distribution ------------- count < 0 | 0 0 |@@@ 10760 1 |@@@@ 10842 2 |@@@@ 10861 3 |@@@ 10820 4 |@@@ 10819 5 |@@@ 10817 6 |@@@@ 10826 7 |@@@@ 10847 8 |@@@@ 10830 9 |@@@@ 10830 |
Em uma arquitetura que não aceita testes profile de resolução arbitrária, executar o script de exemplo produzirá uma distribuição não-uniforme:
# dtrace -s ./restest.d dtrace: script './restest.d' matched 2 probes CPU ID FUNCTION:NAME 0 28321 :tick-1sec value ------------- Distribution ------------- count 4 | 0 5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 107864 6 | 424 7 | 255 8 | 496 9 | 0 |
Nestas arquiteturas, hz pode ser ajustado manualmente em /etc/system para aprimorar a resolução efetiva de profile.
Atualmente, todas as variantes de UltraSPARC (sun4u) aceitam testes profile de resolução arbitrária. Muitas variantes da arquitetura x86 (i86pc) também aceitam testes profile de resolução arbitrária, embora algumas variantes mais antigas não aceitem.
Ao contrário de outros provedores, o provedor profile cria testes dinamicamente, conforme a necessidade. Sendo assim, o teste profile desejado pode não aparecer em uma listagem de todos os testes (por exemplo, usando dtrace -l -P profile), mas o teste será criado quando for ativado explicitamente.
Em arquiteturas que aceitam testes profile de resolução arbitrária, um intervalo de tempo que seja muito curto faria com que a máquina continuamente fizesse interrupções baseadas no tempo, portanto, negando serviço na máquina. Para evitar esta situação, o provedor profile se recusará silenciosamente a criar qualquer teste que resultaria em um intervalo de menos de duzentos microssegundos.
O provedor profile usa o mecanismo de estabilidade do DTrace para descrever suas estabilidades, conforme mostrado na tabela seguinte. Para obter mais informações sobre o mecanismo de estabilidade, consulte o Capítulo 39Estabilidade.
Elemento |
Estabilidade de nome |
Estabilidade de dados |
Classe de dependência |
---|---|---|---|
Provedor |
Desenvolvendo |
Desenvolvendo |
Comum |
Módulo |
Instável |
Instável |
Desconhecida |
Função |
Privada |
Privada |
Desconhecida |
Nome |
Desenvolvendo |
Desenvolvendo |
Comum |
Argumentos |
Desenvolvendo |
Desenvolvendo |
Comum |