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