File:  [local] / rpl / src / gestion_interruptions.c
Revision 1.25: download - view: text, annotated - select for diffs - revision graph
Tue Jun 21 15:26:29 2011 UTC (12 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.

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