![]() ![]() | ![]() |
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 d'affectation des interruptions aux différentes queues 29: ================================================================================ 30: Entrées : s_etat_processus 31: -------------------------------------------------------------------------------- 32: Sorties : 33: -------------------------------------------------------------------------------- 34: Effets de bord : néant 35: ================================================================================ 36: */ 37: 38: void 39: affectation_interruptions_logicielles(struct_processus *s_etat_processus) 40: { 41: int interruption; 42: 43: sig_atomic_t registre; 44: 45: volatile struct_liste_chainee *l_element_courant; 46: struct_liste_chainee *l_element; 47: 48: struct_objet *s_objet_processus; 49: 50: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) 51: { 52: (*s_etat_processus).erreur_systeme = d_es_processus; 53: return; 54: } 55: 56: if ((*s_etat_processus).var_volatile_requete_arret == -1) 57: { 58: // Si une requête d'arrêt est reçue par le processus durant la 59: // phase de verrouillage, on n'empile rien car la structure 60: // processus peut déjà être libérée par le thread de surveillance. 61: 62: (*s_etat_processus).nombre_interruptions_non_affectees = 0; 63: 64: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 65: { 66: (*s_etat_processus).erreur_systeme = d_es_processus; 67: return; 68: } 69: 70: return; 71: } 72: 73: l_element_courant = (*s_etat_processus).l_base_pile_processus; 74: 75: while(l_element_courant != NULL) 76: { 77: /* 78: * On regarde s'il y a quelque chose dans le pipe d'interruptions 79: * du processus fils. 80: * 81: * Cette routine est interruptible par l'arrivée d'une interruption 82: * de type SWI. 83: */ 84: 85: if ((*(*l_element_courant).donnee).type != PRC) 86: { 87: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 88: 89: (*s_etat_processus).erreur_systeme = d_es_processus; 90: return; 91: } 92: 93: if (pthread_mutex_lock(&((*(*((struct_processus_fils *) 94: (*(*l_element_courant).donnee).objet)).thread).mutex)) != 0) 95: { 96: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 97: 98: (*s_etat_processus).erreur_systeme = d_es_processus; 99: return; 100: } 101: 102: if ((*(*((struct_processus_fils *) (*(*l_element_courant).donnee) 103: .objet)).thread).nombre_interruptions_dans_pipe > 0) 104: { 105: registre = (*s_etat_processus).var_volatile_traitement_retarde_stop; 106: (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; 107: 108: if (read_atomic(s_etat_processus, (*(*((struct_processus_fils *) 109: (*(*l_element_courant).donnee) 110: .objet)).thread).pipe_interruptions[0], &interruption, 111: sizeof(interruption)) == sizeof(interruption)) 112: { 113: if (registre == 0) 114: { 115: if ((*s_etat_processus).var_volatile_traitement_retarde_stop 116: == -1) 117: { 118: (*s_etat_processus).var_volatile_requete_arret = -1; 119: } 120: 121: (*s_etat_processus).var_volatile_traitement_retarde_stop 122: = registre; 123: } 124: 125: if ((interruption < 1) || (interruption > 126: d_NOMBRE_INTERRUPTIONS)) 127: { 128: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 129: pthread_mutex_unlock(&((*(*((struct_processus_fils *) 130: (*(*l_element_courant).donnee).objet)).thread) 131: .mutex)); 132: 133: (*s_etat_processus).erreur_systeme = 134: d_es_interruption_invalide; 135: return; 136: } 137: 138: /* 139: * On ne pousse dans les queues des interruptions que les 140: * interruptions qui ne sont pas masquées. 141: */ 142: 143: if ((*s_etat_processus).masque_interruptions[interruption - 1] 144: != 'I') 145: { 146: if ((s_objet_processus = copie_objet(s_etat_processus, 147: (*l_element_courant).donnee, 'P')) == NULL) 148: { 149: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 150: pthread_mutex_unlock(&((*(*((struct_processus_fils *) 151: (*(*l_element_courant).donnee).objet)).thread) 152: .mutex)); 153: 154: (*s_etat_processus).erreur_systeme = 155: d_es_allocation_memoire; 156: return; 157: } 158: 159: // Pile LIFO 160: 161: if (empilement(s_etat_processus, &((*s_etat_processus) 162: .pile_origine_interruptions[interruption - 1]), 163: s_objet_processus) == d_erreur) 164: { 165: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 166: pthread_mutex_unlock(&((*(*((struct_processus_fils *) 167: (*(*l_element_courant).donnee).objet)).thread) 168: .mutex)); 169: return; 170: } 171: 172: (*s_etat_processus).queue_interruptions[interruption - 1]++; 173: (*s_etat_processus).nombre_interruptions_en_queue++; 174: 175: // Transformation en FIFO 176: 177: if ((*s_etat_processus).queue_interruptions 178: [interruption - 1] > 1) 179: { 180: l_element = (*s_etat_processus) 181: .pile_origine_interruptions[interruption - 1]; 182: 183: while((*l_element).suivant != NULL) 184: { 185: l_element = (*l_element).suivant; 186: } 187: 188: (*l_element).suivant = (*s_etat_processus) 189: .pile_origine_interruptions[interruption - 1]; 190: (*s_etat_processus).pile_origine_interruptions 191: [interruption - 1] = 192: (*(*l_element).suivant).suivant; 193: (*(*l_element).suivant).suivant = NULL; 194: } 195: 196: if ((*s_etat_processus).debug == d_vrai) 197: if (((*s_etat_processus).type_debug & 198: d_traitement_interruption) != 0) 199: { 200: if ((*(*((struct_processus_fils *) (*s_objet_processus) 201: .objet)).thread).processus_detache == d_vrai) 202: { 203: if ((*s_etat_processus).langue == 'F') 204: { 205: printf("[%d] Interruption logicielle " 206: "%d empilée en " 207: "provenance du processus %d\n", 208: (int) getpid(), interruption, 209: (int) (*(*((struct_processus_fils *) 210: (*s_objet_processus).objet)).thread) 211: .pid); 212: } 213: else 214: { 215: printf("[%d] Software interrupt %d stacked from" 216: " process %d\n", interruption, 217: (int) getpid(), 218: (int) (*(*((struct_processus_fils *) 219: (*s_objet_processus).objet)).thread) 220: .pid); 221: } 222: } 223: else 224: { 225: if ((*s_etat_processus).langue == 'F') 226: { 227: printf("[%d] Interruption logicielle " 228: "%d empilée en " 229: "provenance du thread %lld\n", 230: (int) getpid(), interruption, (integer8) 231: (*(*((struct_processus_fils *) 232: (*s_objet_processus).objet)).thread) 233: .tid); 234: } 235: else 236: { 237: printf("[%d] Software interrupt %d stacked from" 238: " process %lld\n", interruption, 239: (int) getpid(), (integer8) 240: (*(*((struct_processus_fils *) 241: (*s_objet_processus).objet)).thread) 242: .tid); 243: } 244: } 245: 246: fflush(stdout); 247: } 248: } 249: 250: (*(*((struct_processus_fils *) (*(*l_element_courant).donnee) 251: .objet)).thread).nombre_interruptions_dans_pipe--; 252: (*s_etat_processus).nombre_interruptions_non_affectees--; 253: } 254: else 255: { 256: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 257: pthread_mutex_unlock(&((*(*((struct_processus_fils *) 258: (*(*l_element_courant).donnee).objet)).thread).mutex)); 259: 260: if (registre == 0) 261: { 262: if ((*s_etat_processus).var_volatile_traitement_retarde_stop 263: == -1) 264: { 265: (*s_etat_processus).var_volatile_requete_arret = -1; 266: } 267: 268: (*s_etat_processus).var_volatile_traitement_retarde_stop 269: = registre; 270: } 271: 272: (*s_etat_processus).erreur_systeme = d_es_interruption_invalide; 273: return; 274: } 275: } 276: 277: if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) 278: (*(*l_element_courant).donnee).objet)).thread).mutex)) != 0) 279: { 280: pthread_mutex_unlock(&((*s_etat_processus).mutex)); 281: 282: (*s_etat_processus).erreur_systeme = d_es_processus; 283: return; 284: } 285: 286: l_element_courant = (*l_element_courant).suivant; 287: } 288: 289: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) 290: { 291: (*s_etat_processus).erreur_systeme = d_es_processus; 292: return; 293: } 294: 295: return; 296: } 297: 298: 299: /* 300: ================================================================================ 301: Fonction de traitement des différentes interruptions 302: ================================================================================ 303: Entrées : s_etat_processus 304: -------------------------------------------------------------------------------- 305: Sorties : 306: -------------------------------------------------------------------------------- 307: Effets de bord : néant 308: ================================================================================ 309: */ 310: 311: void 312: traitement_interruptions_logicielles(struct_processus *s_etat_processus) 313: { 314: int i; 315: 316: logical1 drapeau_erreur; 317: logical1 processus; 318: logical1 registre_arret_si_exception; 319: 320: pid_t pid; 321: pthread_t tid; 322: 323: struct_objet *s_objet_processus; 324: 325: unsigned char registre; 326: unsigned char tampon[22]; 327: 328: /* 329: * Les interruptions sont non interruptibles. 330: */ 331: 332: if (((*s_etat_processus).traitement_interruption == 'Y') || 333: ((*s_etat_processus).traitement_interruptible == 'N')) 334: { 335: return; 336: } 337: 338: registre = (*s_etat_processus).traitement_interruption; 339: (*s_etat_processus).traitement_interruption = 'Y'; 340: 341: /* 342: * Lancement d'une interruption. Les interruptions sont d'autant plus 343: * prioritaires que leur numéro est faible. 344: */ 345: 346: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) 347: { 348: pid = 0; 349: tid = 0; 350: processus = d_faux; 351: 352: if ((*s_etat_processus).queue_interruptions[i] > 0) 353: { 354: if ((*s_etat_processus).masque_interruptions[i] == 'N') 355: { 356: /* 357: * Exécution de la i-ème interruption si celle-ci existe. Dans 358: * le cas contraire, une erreur d'exécution est renvoyée. 359: */ 360: 361: if (((*s_etat_processus).corps_interruptions[i] != NULL) && 362: ((*s_etat_processus).pile_origine_interruptions[i] 363: != NULL)) 364: { 365: if (depilement(s_etat_processus, &((*s_etat_processus) 366: .pile_origine_interruptions[i]), 367: &s_objet_processus) == d_erreur) 368: { 369: (*s_etat_processus).traitement_interruption = 370: registre; 371: (*s_etat_processus).erreur_execution = 372: d_ex_interruption_invalide; 373: return; 374: } 375: 376: if (empilement(s_etat_processus, &((*s_etat_processus) 377: .l_base_pile), s_objet_processus) == d_erreur) 378: { 379: (*s_etat_processus).traitement_interruption = 380: registre; 381: return; 382: } 383: 384: if ((*s_etat_processus).debug == d_vrai) 385: if (((*s_etat_processus).type_debug & 386: d_traitement_interruption) != 0) 387: { 388: if ((*s_etat_processus).langue == 'F') 389: { 390: if ((processus = (*(*((struct_processus_fils *) 391: (*s_objet_processus).objet)).thread) 392: .processus_detache) == d_faux) 393: { 394: printf("[%d] Traitement de l'interruption " 395: "logicielle %d en provenance du thread " 396: "%llu\n", (int) getpid(), i + 1, 397: (unsigned long long) 398: (tid = (*(*((struct_processus_fils *) 399: (*s_objet_processus).objet)).thread) 400: .tid)); 401: } 402: else 403: { 404: printf("[%d] Traitement de l'interruption " 405: "logicielle %d en provenance du " 406: "processus " 407: "%d\n", (int) getpid(), i + 1, (int) 408: (pid = (*(*((struct_processus_fils *) 409: (*s_objet_processus).objet)).thread) 410: .pid)); 411: } 412: } 413: else 414: { 415: if ((processus = (*(*((struct_processus_fils *) 416: (*s_objet_processus).objet)).thread) 417: .processus_detache) == d_faux) 418: { 419: printf("[%d] Start software interrupt " 420: "%d from thread " 421: "%llu\n", (int) getpid(), i + 1, 422: (unsigned long long) 423: (tid = (*(*((struct_processus_fils *) 424: (*s_objet_processus).objet)).thread) 425: .tid)); 426: } 427: else 428: { 429: printf("[%d] Start software interrupt " 430: "%d from process " 431: "%d\n", (int) getpid(), i + 1, (int) 432: (pid = (*(*((struct_processus_fils *) 433: (*s_objet_processus).objet)).thread) 434: .pid)); 435: } 436: } 437: 438: fflush(stdout); 439: } 440: 441: (*s_etat_processus).nombre_interruptions_en_queue--; 442: (*s_etat_processus).queue_interruptions[i]--; 443: 444: registre_arret_si_exception = 445: (*s_etat_processus).arret_si_exception; 446: (*s_etat_processus).arret_si_exception = d_vrai; 447: 448: if ((*s_etat_processus).profilage == d_vrai) 449: { 450: sprintf(tampon, "Software interrupt %-2d", i + 1); 451: profilage(s_etat_processus, tampon); 452: 453: if ((*s_etat_processus).erreur_systeme != d_es) 454: { 455: return; 456: } 457: } 458: 459: drapeau_erreur = evaluation(s_etat_processus, 460: (*s_etat_processus).corps_interruptions[i], 'E'); 461: 462: if ((*s_etat_processus).profilage == d_vrai) 463: { 464: profilage(s_etat_processus, NULL); 465: } 466: 467: if (drapeau_erreur == d_absence_erreur) 468: { 469: (*s_etat_processus).arret_si_exception = 470: registre_arret_si_exception; 471: } 472: else 473: { 474: if ((((*s_etat_processus).erreur_execution != d_ex) || 475: ((*s_etat_processus).exception != d_ep) || 476: ((*s_etat_processus).erreur_systeme != d_es)) && 477: ((*s_etat_processus).core == d_vrai) && 478: ((*s_etat_processus) 479: .var_volatile_traitement_sigint == 0)) 480: { 481: printf("\n"); 482: 483: if ((*s_etat_processus).langue == 'F') 484: { 485: printf("+++Information : " 486: "Génération du fichier rpl-core " 487: "[%d]\n", (int) getpid()); 488: } 489: else 490: { 491: printf("+++Information : " 492: "Writing rpl-core file [%d]\n", 493: (int) getpid()); 494: } 495: 496: rplcore(s_etat_processus); 497: 498: if ((*s_etat_processus).langue == 'F') 499: { 500: printf("+++Information : " 501: "Processus tracé [%d]\n", 502: (int) getpid()); 503: } 504: else 505: { 506: printf("+++Information : Done [%d]\n", 507: (int) getpid()); 508: } 509: 510: printf("\n"); 511: fflush(stdout); 512: } 513: 514: } 515: 516: if ((*s_etat_processus).debug == d_vrai) 517: if (((*s_etat_processus).type_debug & 518: d_traitement_interruption) != 0) 519: { 520: if ((*s_etat_processus).langue == 'F') 521: { 522: if (processus == d_faux) 523: { 524: printf("[%d] Fin de l'interruption logicielle" 525: " %d en provenance du thread %llu\n", 526: (int) getpid(), i + 1, 527: (unsigned long long) tid); 528: } 529: else 530: { 531: printf("[%d] Fin de l'interruption logicielle" 532: " %d en provenance du processus %d\n", 533: (int) getpid(), i + 1, (int) pid); 534: } 535: } 536: else 537: { 538: if (processus == d_faux) 539: { 540: printf("[%d] Stop software interrupt " 541: "%d from thread " 542: "%llu\n", (int) getpid(), i + 1, 543: (unsigned long long) pid); 544: } 545: else 546: { 547: printf("[%d] Stop software interrupt " 548: "%d from process " 549: "%d\n", (int) getpid(), i + 1, 550: (int) pid); 551: } 552: } 553: 554: fflush(stdout); 555: } 556: 557: if ((drapeau_erreur == d_erreur) && 558: ((*s_etat_processus).erreur_execution == d_ex)) 559: { 560: if (((*s_etat_processus).erreur_execution == d_ex) && 561: ((*s_etat_processus).erreur_systeme == d_es)) 562: { 563: (*s_etat_processus).erreur_execution = 564: d_ex_erreur_evaluation; 565: } 566: } 567: } 568: else 569: { 570: (*s_etat_processus).erreur_execution = 571: d_ex_interruption_invalide; 572: } 573: } 574: } 575: } 576: 577: (*s_etat_processus).traitement_interruption = registre; 578: 579: return; 580: } 581: 582: // vim: ts=4