File:  [local] / rpl / src / gestion_interruptions.c
Revision 1.20.2.1: download - view: text, annotated - select for diffs - revision graph
Mon Apr 11 13:02:15 2011 UTC (13 years ago) by bertrand
Branches: rpl-4_0
CVS tags: rpl-4_0_22
Diff to: branchpoint 1.20: preferred, colored
En route vers la 4.0.22.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.22
    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

CVSweb interface <joel.bertrand@systella.fr>