File:  [local] / rpl / src / gestion_interruptions.c
Revision 1.70: download - view: text, annotated - select for diffs - revision graph
Fri Jan 10 11:15:42 2020 UTC (4 years, 2 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_32, HEAD
Modification du copyright.

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

CVSweb interface <joel.bertrand@systella.fr>