Annotation of rpl/src/profilage.c, revision 1.1
1.1 ! bertrand 1: /*
! 2: ================================================================================
! 3: RPL/2 (R) version 4.0.9
! 4: Copyright (C) 1989-2010 Dr. BERTRAND Joël
! 5:
! 6: This file is part of RPL/2.
! 7:
! 8: RPL/2 is free software; you can redistribute it and/or modify it
! 9: under the terms of the CeCILL V2 License as published by the french
! 10: CEA, CNRS and INRIA.
! 11:
! 12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
! 13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
! 14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
! 15: for more details.
! 16:
! 17: You should have received a copy of the CeCILL License
! 18: along with RPL/2. If not, write to info@cecill.info.
! 19: ================================================================================
! 20: */
! 21:
! 22:
! 23: #include "rpl.conv.h"
! 24:
! 25:
! 26: /*
! 27: ================================================================================
! 28: Fonction de profilage
! 29: ================================================================================
! 30: Entrées : pointeur sur une structure processus
! 31: --------------------------------------------------------------------------------
! 32: Sorties :
! 33: --------------------------------------------------------------------------------
! 34: Effets de bord : néant
! 35: ================================================================================
! 36: */
! 37:
! 38: // Si *fonction est non nul, profilage considère un appel à la fonction
! 39: // *fonction. Si *fonction est nul, il s'agit du retour de la fonction.
! 40:
! 41: void
! 42: profilage(struct_processus *s_etat_processus, unsigned char *fonction)
! 43: {
! 44: struct_liste_profilage *l_element_cible;
! 45: struct_liste_profilage *l_element_courant;
! 46: struct_liste_profilage2 *l_element_fonction;
! 47:
! 48: struct timeval horodatage;
! 49: struct timeval temps;
! 50:
! 51: /*
! 52: * Les statistiques sont écrites dans un fichier rpl-profile-pid-tid
! 53: * à chaque minute.
! 54: */
! 55:
! 56: gettimeofday(&horodatage, NULL);
! 57:
! 58: if (fonction != NULL)
! 59: {
! 60: /*
! 61: * Recherche d'une occurrence de l'appel de la fonction
! 62: * et arrêt du compteur de la fonction appelante
! 63: */
! 64:
! 65: l_element_courant = (*s_etat_processus).pile_profilage;
! 66: l_element_cible = NULL;
! 67:
! 68: while(l_element_courant != NULL)
! 69: {
! 70: if (strcmp((*l_element_courant).fonction, fonction) == 0)
! 71: {
! 72: l_element_cible = l_element_courant;
! 73: }
! 74:
! 75: if ((*s_etat_processus).pile_profilage_fonctions != NULL)
! 76: {
! 77: if (strcmp((*l_element_courant).fonction,
! 78: (*(*s_etat_processus).pile_profilage_fonctions)
! 79: .fonction) == 0)
! 80: {
! 81: if (horodatage.tv_usec < (*l_element_courant)
! 82: .dernier_appel.tv_usec)
! 83: {
! 84: // Avec retenue
! 85: temps.tv_usec = (1000000 + horodatage.tv_usec)
! 86: - (*l_element_courant).dernier_appel.tv_usec;
! 87: temps.tv_sec = horodatage.tv_sec
! 88: - ((*l_element_courant).dernier_appel.tv_sec
! 89: + 1);
! 90: }
! 91: else
! 92: {
! 93: // Sans retenue
! 94: temps.tv_usec = horodatage.tv_usec
! 95: - (*l_element_courant).dernier_appel.tv_usec;
! 96: temps.tv_sec = horodatage.tv_sec
! 97: - (*l_element_courant).dernier_appel.tv_sec;
! 98: }
! 99:
! 100: // Cumul
! 101:
! 102: (*l_element_courant).cumul.tv_usec += temps.tv_usec;
! 103: (*l_element_courant).cumul.tv_sec += temps.tv_sec;
! 104:
! 105: if ((*l_element_courant).cumul.tv_usec >= 1000000)
! 106: {
! 107: (*l_element_courant).cumul.tv_usec -= 1000000;
! 108: (*l_element_courant).cumul.tv_sec++;
! 109: }
! 110: }
! 111: }
! 112:
! 113: l_element_courant = (*l_element_courant).suivant;
! 114: }
! 115:
! 116: l_element_courant = l_element_cible;
! 117:
! 118: if (l_element_courant == NULL)
! 119: {
! 120: // Nouvel appel
! 121:
! 122: if ((l_element_courant = malloc(sizeof(struct_liste_profilage)))
! 123: == NULL)
! 124: {
! 125: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 126: return;
! 127: }
! 128:
! 129: (*l_element_courant).suivant = (*s_etat_processus).pile_profilage;
! 130: (*s_etat_processus).pile_profilage = l_element_courant;
! 131:
! 132: if (((*l_element_courant).fonction = malloc((strlen(fonction) + 1) *
! 133: sizeof(unsigned char))) == NULL)
! 134: {
! 135: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 136: return;
! 137: }
! 138:
! 139: strcpy((*l_element_courant).fonction, fonction);
! 140:
! 141: (*l_element_courant).cumul.tv_sec = 0;
! 142: (*l_element_courant).cumul.tv_usec = 0;
! 143: (*l_element_courant).nombre_appels = 0;
! 144: }
! 145:
! 146: (*l_element_courant).dernier_appel = horodatage;
! 147: (*l_element_courant).nombre_appels++;
! 148:
! 149: // Empilement
! 150:
! 151: if ((l_element_fonction = malloc(sizeof(struct_liste_profilage2)))
! 152: == NULL)
! 153: {
! 154: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 155: return;
! 156: }
! 157:
! 158: if (((*l_element_fonction).fonction = malloc((strlen(fonction) + 1) *
! 159: sizeof(unsigned char))) == NULL)
! 160: {
! 161: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 162: return;
! 163: }
! 164:
! 165: strcpy((*l_element_fonction).fonction, fonction);
! 166: (*l_element_fonction).suivant = (*s_etat_processus)
! 167: .pile_profilage_fonctions;
! 168: (*s_etat_processus).pile_profilage_fonctions = l_element_fonction;
! 169: }
! 170: else
! 171: {
! 172: if ((*s_etat_processus).pile_profilage_fonctions == NULL)
! 173: {
! 174: (*s_etat_processus).erreur_execution = d_ex_erreur_profilage;
! 175: return;
! 176: }
! 177:
! 178: l_element_courant = (*s_etat_processus).pile_profilage;
! 179:
! 180: while(l_element_courant != NULL)
! 181: {
! 182: if (strcmp((*l_element_courant).fonction,
! 183: (*(*s_etat_processus).pile_profilage_fonctions).fonction)
! 184: == 0)
! 185: {
! 186: break;
! 187: }
! 188:
! 189: l_element_courant = (*l_element_courant).suivant;
! 190: }
! 191:
! 192: BUG(l_element_courant == NULL, printf("Function %s not found!\n",
! 193: (*(*s_etat_processus).pile_profilage_fonctions).fonction));
! 194:
! 195: // Soustraction des temps
! 196:
! 197: if (horodatage.tv_usec < (*l_element_courant).dernier_appel.tv_usec)
! 198: {
! 199: // Avec retenue
! 200: temps.tv_usec = (1000000 + horodatage.tv_usec)
! 201: - (*l_element_courant).dernier_appel.tv_usec;
! 202: temps.tv_sec = horodatage.tv_sec
! 203: - ((*l_element_courant).dernier_appel.tv_sec + 1);
! 204: }
! 205: else
! 206: {
! 207: // Sans retenue
! 208: temps.tv_usec = horodatage.tv_usec
! 209: - (*l_element_courant).dernier_appel.tv_usec;
! 210: temps.tv_sec = horodatage.tv_sec
! 211: - (*l_element_courant).dernier_appel.tv_sec;
! 212: }
! 213:
! 214: // Cumul
! 215:
! 216: (*l_element_courant).cumul.tv_usec += temps.tv_usec;
! 217: (*l_element_courant).cumul.tv_sec += temps.tv_sec;
! 218:
! 219: if ((*l_element_courant).cumul.tv_usec >= 1000000)
! 220: {
! 221: (*l_element_courant).cumul.tv_usec -= 1000000;
! 222: (*l_element_courant).cumul.tv_sec++;
! 223: }
! 224:
! 225: // Dépilement
! 226:
! 227: l_element_fonction = (*s_etat_processus).pile_profilage_fonctions;
! 228: (*s_etat_processus).pile_profilage_fonctions =
! 229: (*l_element_fonction).suivant;
! 230:
! 231: free((*l_element_fonction).fonction);
! 232: free(l_element_fonction);
! 233:
! 234: // Relance du compteur de la fonction en cours
! 235:
! 236: if ((*s_etat_processus).pile_profilage_fonctions != NULL)
! 237: {
! 238: l_element_courant = (*s_etat_processus).pile_profilage;
! 239:
! 240: while(l_element_courant != NULL)
! 241: {
! 242: if (strcmp((*l_element_courant).fonction, (*(*s_etat_processus)
! 243: .pile_profilage_fonctions).fonction) == 0)
! 244: {
! 245: break;
! 246: }
! 247:
! 248: l_element_courant = (*l_element_courant).suivant;
! 249: }
! 250:
! 251: BUG(l_element_courant == NULL, printf("Function %s not found!\n",
! 252: (*(*s_etat_processus).pile_profilage_fonctions).fonction));
! 253: (*l_element_courant).dernier_appel = horodatage;
! 254: }
! 255: }
! 256:
! 257: if ((horodatage.tv_sec - (*s_etat_processus).horodatage_profilage.tv_sec)
! 258: >= 60)
! 259: {
! 260: ecriture_profil(s_etat_processus);
! 261: (*s_etat_processus).horodatage_profilage = horodatage;
! 262: }
! 263:
! 264: return;
! 265: }
! 266:
! 267: void
! 268: ecriture_profil(struct_processus *s_etat_processus)
! 269: {
! 270: double fraction;
! 271: double temps;
! 272: double total;
! 273:
! 274: file *fichier;
! 275:
! 276: struct_liste_profilage *l_element_courant;
! 277:
! 278: struct timeval cumul;
! 279:
! 280: unsigned char *nom;
! 281:
! 282: l_element_courant = (*s_etat_processus).pile_profilage;
! 283:
! 284: // Calcul du temps total
! 285:
! 286: cumul.tv_sec = 0;
! 287: cumul.tv_usec = 0;
! 288:
! 289: while(l_element_courant != NULL)
! 290: {
! 291: cumul.tv_usec += (*l_element_courant).cumul.tv_usec;
! 292: cumul.tv_sec += (*l_element_courant).cumul.tv_sec;
! 293:
! 294: if (cumul.tv_usec >= 1000000)
! 295: {
! 296: cumul.tv_usec -= 1000000;
! 297: cumul.tv_sec++;
! 298: }
! 299:
! 300: l_element_courant = (*l_element_courant).suivant;
! 301: }
! 302:
! 303: total = cumul.tv_sec + (((double) cumul.tv_usec) / 1000000);
! 304:
! 305: // Création du fichier
! 306:
! 307: if ((nom = malloc((strlen(ds_rplprofile) + 64 + 1) * sizeof(unsigned char)))
! 308: == NULL)
! 309: {
! 310: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 311: return;
! 312: }
! 313:
! 314: snprintf(nom, strlen(ds_rplprofile) + 64 + 1,
! 315: "%s-%lu-%lu", ds_rplprofile, (unsigned long) getpid(),
! 316: (unsigned long) pthread_self());
! 317:
! 318: if ((fichier = fopen(nom, "w+")) == NULL)
! 319: {
! 320: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 321: free(nom);
! 322:
! 323: return;
! 324: }
! 325:
! 326: free(nom);
! 327:
! 328: // Préparation du résultat
! 329:
! 330: if (fprintf(fichier, "RPL/2 statistics\n\n") < 0)
! 331: {
! 332: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 333: return;
! 334: }
! 335:
! 336: if (fprintf(fichier, "Process : %lu\n", (unsigned long)
! 337: getpid()) < 0)
! 338: {
! 339: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 340: return;
! 341: }
! 342:
! 343: if (fprintf(fichier, "Thread : %lu\n", (unsigned long)
! 344: pthread_self()) < 0)
! 345: {
! 346: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 347: return;
! 348: }
! 349:
! 350: if (fprintf(fichier, "Elapsed Time : %.2fs\n\n", total) < 0)
! 351: {
! 352: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 353: return;
! 354: }
! 355:
! 356: if (fprintf(fichier, "Calls_________ Time____________ Ratio__ Normal_ "
! 357: " Object______________________\n") < 0)
! 358: {
! 359: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 360: return;
! 361: }
! 362:
! 363: l_element_courant = (*s_etat_processus).pile_profilage;
! 364:
! 365: while(l_element_courant != NULL)
! 366: {
! 367: temps = (*l_element_courant).cumul.tv_sec +
! 368: (((double) (*l_element_courant).cumul.tv_usec) / 1000000);
! 369: fraction = 100 * (temps / total);
! 370:
! 371: if (fprintf(fichier, "<%012lld> %15.2fs (%6.2f%%/%6.2f%%) : %s\n",
! 372: (*l_element_courant).nombre_appels,
! 373: temps, fraction, fraction / (*l_element_courant).nombre_appels,
! 374: (*l_element_courant).fonction) < 0)
! 375: {
! 376: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 377: return;
! 378: }
! 379:
! 380: l_element_courant = (*l_element_courant).suivant;
! 381: }
! 382:
! 383: if (fclose(fichier) != 0)
! 384: {
! 385: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 386: return;
! 387: }
! 388:
! 389: return;
! 390: }
! 391:
! 392: void
! 393: liberation_profil(struct_processus *s_etat_processus)
! 394: {
! 395: struct_liste_profilage *l_element_courant;
! 396: struct_liste_profilage2 *l_element_fonction;
! 397:
! 398: while((*s_etat_processus).pile_profilage != NULL)
! 399: {
! 400: l_element_courant = (*s_etat_processus).pile_profilage;
! 401: (*s_etat_processus).pile_profilage =
! 402: (*(*s_etat_processus).pile_profilage).suivant;
! 403:
! 404: free((*l_element_courant).fonction);
! 405: free(l_element_courant);
! 406: }
! 407:
! 408: while((*s_etat_processus).pile_profilage_fonctions != NULL)
! 409: {
! 410: l_element_fonction = (*s_etat_processus).pile_profilage_fonctions;
! 411: (*s_etat_processus).pile_profilage_fonctions =
! 412: (*(*s_etat_processus).pile_profilage_fonctions).suivant;
! 413:
! 414: free((*l_element_fonction).fonction);
! 415: free(l_element_fonction);
! 416: }
! 417:
! 418: return;
! 419: }
! 420:
! 421: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>