Manuel de suivi dynamique Solaris

Variables et expressions arithmétiques

Notre prochain programme donné à titre d'exemple utilise le fournisseur profile DTrace pour implémenter un compteur temporel simple. Le fournisseur de profil permet de créer de nouvelles sondes en fonction des descriptions trouvées dans votre programme D. Si vous créez une sonde appelée profile:::tick-nsec pour certains nombres entiers n, le fournisseur de profil va créer une sonde qui se déclenche toutes les n secondes. Entrez le code source suivant et enregistrez-le dans le fichier 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);
}

Lorsqu'il est exécuté, le programme compte le nombre de secondes écoulées avant que vous n'appuyiez sur Control-C puis affiche le total à la fin :


# 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
#

Les trois premières lignes du programme sont des lignes de commentaire expliquant la finalité du programme. À l'instar des langages de programmation C, C++ et Java, le compilateur D ignore tous les caractères compris entre les symboles /* et */. Les commentaires peuvent être utilisés n'importe où dans un programme D, à l'intérieur comme à l'extérieur de vos clauses de sonde.

La clause de la sonde BEGIN définit une nouvelle variable appelée i et lui assigne la valeur de nombre entier égal à zéro avec l'instruction :

i = 0;

Contrairement aux langages de programmation C, C++ et Java, il suffit d'utiliser les variables D dans une instruction de programme pour les créer ; aucune déclaration de variable explicite n'est requise. Lorsqu'une variable est utilisée pour la première fois dans un programme, son type est défini en fonction du type de sa première assignation. Chaque variable se voit assigner un seul type tout au long de la vie du programme ; les références ultérieures doivent donc correspondre au type de l'assignation d'origine. Dans counter.d, la variable i se voit d'abord assigner la valeur constante de nombre entier égal à zéro. Son type est donc défini sur int. D fournit les mêmes types de données de nombres entiers de base que C, notamment :

char

Caractère ou nombre entier à octet unique 

int

Nombre entier par défaut 

short

Nombre entier court 

long

Nombre entier long 

long long

Nombre entier long étendu 

Les formats de ces types dépendent du modèle de données du noyau du système d'exploitation, décrit dans le Chapitre2Types, opérateurs et expressions D fournit également des noms conviviaux intégrés pour les types de nombres entiers signés et non signés de taille fixe différente, ainsi que des milliers d'autres types définis par le système d'exploitation.

La partie centrale de counter.d est la clause de sonde qui incrémente le compteur i :

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

Cette clause nomme la sonde profile:::tick-1sec, indiquant au fournisseur profile qu'il doit créer une nouvelle sonde qui se déclenche une fois par seconde sur un processeur disponible. La clause comporte deux instructions : la première assigne à i la valeur précédente plus un, la seconde procède au suivi de la nouvelle valeur de i. Tous les opérateurs arithmétiques habituels de C sont disponibles en D ; la liste complète figure dans le Chapitre2Types, opérateurs et expressions Ainsi, comme dans C, l'opérateur ++ peut être utilisé comme abrégé pour incrémenter de un la variable correspondante. La fonction trace() prend comme argument n'importe quelle expression D, de façon à écrire counter.d de façon plus concise, comme suit :

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

Si vous souhaitez contrôler de façon explicite le type de variable i, vous pouvez mettre entre parenthèses le type souhaité lors de son assignation, afin de forcer le type du nombre entier égal à zéro vers un type spécifique. Par exemple, si vous souhaitez déterminer le nombre maximum de char en D, vous pouvez modifier la clause BEGIN comme suit :

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

Après l'exécution de counter.d, vous verrez la valeur faisant l'objet d'un suivi augmenter puis revenir à zéro au bout de quelque temps, une fois la recherche circulaire effectuée. Si l'attente vous semble trop longue, essayez de modifier le nom de la sonde profile en profile:::tick-100msec pour que l'incrémentation se fasse toutes les 100 millisecondes, soit 10 fois par seconde.