File:  [local] / rpl / src / gestion_interruptions.c
Revision 1.6: download - view: text, annotated - select for diffs - revision graph
Wed Apr 7 13:45:03 2010 UTC (14 years ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_0_14, HEAD
En route pour la 4.0.14 !

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