File:  [local] / rpl / src / gestion_interruptions.c
Revision 1.51: download - view: text, annotated - select for diffs - revision graph
Fri Apr 25 07:37:29 2014 UTC (10 years ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_18, HEAD
En route pour la 4.1.18.

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

CVSweb interface <joel.bertrand@systella.fr>