Guia de rastreamento dinâmico Solaris

Variáveis e expressões aritméticas

Nosso próximo programa de exemplo utiliza o provedor profile do DTrace para implementar um contador simples baseado em hora. O provedor de perfil pode criar novos testes com base nas descrições encontradas no programa em D. Se você criar um teste chamado profile:::tick-nsec para algum inteiro n, o provedor de perfil criará um teste que dispare a cada n segundos. Digite o seguinte código-fonte e salve-o em um arquivo chamado counter.d:

/*
 * Count off and report the number of seconds elapsed
 */
dtrace:::BEGIN
{
	i = 0;
}

profile:::tick-1sec
{
	i = i + 1;
	trace(i);
}

dtrace:::END
{
	trace(i);
}

Quando executado, o programa conta o número de segundos decorridos até que você pressione Control-C e depois imprime o total no final:


# dtrace -s counter.d
dtrace: script 'counter.d' matched 3 probes
CPU     ID                    FUNCTION:NAME
  0  25499                       :tick-1sec         1
  0  25499                       :tick-1sec         2
  0  25499                       :tick-1sec         3
  0  25499                       :tick-1sec         4
  0  25499                       :tick-1sec         5
  0  25499                       :tick-1sec         6
^C
  0      2                             :END         6
#

As primeiras três linhas do programa são um comentário para explicar o que o programa faz. Similar às linguagens de programação C, C++ e Java, o compilador de D ignora os caracteres entre os símbolos /* e */. Os comentários podem ser usados em qualquer lugar de um programa em D, incluindo dentro e fora das cláusulas do teste.

A cláusula do teste BEGIN define uma nova variável denominada i e atribui a ela o valor inteiro zero usando a instrução:

i = 0;

Ao contrário das linguagens de programação C, C++ e Java, as variáveis de D podem ser criadas simplesmente usando-as em uma instrução do programa; declarações explícitas de variável não são necessárias. Quando uma variável é usada pela primeira vez em um programa, o tipo da variável é definido com base no tipo da sua primeira atribuição. Cada variável possui somente um tipo durante a duração do programa, sendo assim, as referências subseqüentes devem estar de acordo com o mesmo tipo da atribuição inicial. Em counter.d, a primeira atribuição da variável i é uma constante de inteiro zero, sendo assim, seu tipo é definido como int. D fornece os mesmos tipos básicos de dados de inteiro que C, incluindo:

char

Caractere ou inteiro de byte único 

int

Inteiro padrão 

short

Inteiro curto 

long

Inteiro longo 

long long

Inteiro longo estendido 

Os tamanhos destes tipos dependem do modelo de dados do kernel do sistema operacional, descrito no Capítulo 2Tipos, operadores e expressões. D também fornece nomes amigáveis internos para tipos de inteiros atribuídos e não atribuídos de vários tamanhos fixos, assim como milhares de outros tipos que são definidos pelo sistema operacional.

A parte central de counter.d é a cláusula do teste que incrementa o contador i:

profile:::tick-1sec
{
	i = i + 1;
	trace(i);
}

Esta cláusula nomeia o teste profile:::tick-1sec, que informa ao provedor profile para criar um novo teste que é disparado uma vez por segundo em um processador disponível. A cláusula contém duas instruções, a primeira atribuindo i como o valor anterior mais um e a segunda rastreando o novo valor de i. Todos os operadores aritméticos usuais de C estão disponíveis em D. A lista completa pode ser encontrada no Capítulo 2Tipos, operadores e expressões. Além disso, como em C, o operador ++ pode ser usado como abreviação para incrementar a variável correspondente em um. A função trace() toma qualquer expressão de D como argumento, assim, você poderia escrever counter.d de forma mais concisa, como a seguir:

profile:::tick-1sec
{
	trace(++i);
}

Se você desejar controlar explicitamente o tipo da variável i, poderá colocar o tipo desejado entre parênteses quando atribuí-lo para converter o inteiro zero em um tipo específico. Por exemplo, caso desejasse determinar o tamanho máximo de um char em D, você poderia alterar a cláusula BEGIN da seguinte maneira:

dtrace:::BEGIN
{
	i = (char)0;
}

Após executar counter.d por um tempo, você verá o valor tracejado aumentar e depois voltar para zero. Se você não tiver paciência para esperar o valor voltar para zero, tente alterar o nome do teste profile para profile:::tick-100msec para fazer um contador que aumente a cada 100 milissegundos ou 10 vezes por segundo.