![]() ![]() | ![]() |
Passage de la branche 4.1 en branche stable.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.0 4: Copyright (C) 1989-2011 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