File:  [local] / rpl / src / instructions_s10.c
Revision 1.51: download - view: text, annotated - select for diffs - revision graph
Sat Nov 26 10:01:31 2011 UTC (12 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.5. Correction d'un bug mineur sur les mutexes.
Préparation d'un mécanisme pour éviter qu'un mutex soit déverrouillé
depuis un thread qui ne l'a pas verrouillé.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.5
    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 'spawn'
   29: ================================================================================
   30:   Entrées :
   31: --------------------------------------------------------------------------------
   32:   Sorties :
   33: --------------------------------------------------------------------------------
   34:   Effets de bord : néant
   35: ================================================================================
   36: */
   37: 
   38: void
   39: instruction_spawn(struct_processus *s_etat_processus)
   40: {
   41:     logical1                    drapeau;
   42:     logical1                    variable_partagee;
   43: 
   44:     pthread_attr_t              attributs;
   45: 
   46:     pthread_mutexattr_t         attributs_mutex;
   47: 
   48:     pthread_t                   thread_id;
   49:     pthread_t                   thread_surveillance;
   50: 
   51:     struct_descripteur_thread   *s_argument_thread;
   52: 
   53:     struct_liste_chainee        *l_element_courant;
   54: 
   55:     struct_objet                *s_copie;
   56:     struct_objet                *s_objet;
   57:     struct_objet                *s_objet_resultat;
   58:     struct_objet                *s_objet_systeme;
   59: 
   60:     struct_processus            *s_nouvel_etat_processus;
   61: 
   62:     struct timespec             attente;
   63: 
   64:     (*s_etat_processus).erreur_execution = d_ex;
   65: 
   66:     if ((*s_etat_processus).affichage_arguments == 'Y')
   67:     {
   68:         printf("\n  SPAWN ");
   69: 
   70:         if ((*s_etat_processus).langue == 'F')
   71:         {
   72:             printf("(lancement d'un thread)\n\n");
   73:         }
   74:         else
   75:         {
   76:             printf("(create thread)\n\n");
   77:         }
   78: 
   79:         printf("    1: %s, %s\n", d_NOM, d_RPN);
   80:         printf("->  1: %s\n", d_PRC);
   81: 
   82:         return;
   83:     }
   84:     else if ((*s_etat_processus).test_instruction == 'Y')
   85:     {
   86:         (*s_etat_processus).nombre_arguments = -1;
   87:         return;
   88:     }
   89: 
   90:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
   91:     {
   92:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
   93:         {
   94:             return;
   95:         }
   96:     }
   97: 
   98:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
   99:             &s_objet) == d_erreur)
  100:     {
  101:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
  102:         return;
  103:     }
  104: 
  105:     /*
  106:      * Une routine fille doit pouvoir renvoyer des objets au processus
  107:      * père au travers de la fonction SEND. Il ne peut donc s'agir que
  108:      * d'une fonction ou d'une expression RPN.
  109:      */
  110: 
  111:     if (((*s_objet).type != NOM) && ((*s_objet).type != RPN))
  112:     {
  113:         liberation(s_etat_processus, s_objet);
  114: 
  115:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
  116:         return;
  117:     }
  118: 
  119:     /*
  120:      * Si l'argument est de type NOM, il faut que la variable correspondante
  121:      * soit une variable de type RPN.
  122:      */
  123: 
  124:     variable_partagee = d_faux;
  125:     s_copie = NULL;
  126: 
  127:     if ((*s_objet).type == NOM)
  128:     {
  129:         if (recherche_variable(s_etat_processus, (*((struct_nom *)
  130:                 (*s_objet).objet)).nom) == d_vrai)
  131:         {
  132:             if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
  133:             {
  134:                 if (pthread_mutex_lock(&((*(*s_etat_processus)
  135:                         .s_liste_variables_partagees).mutex)) != 0)
  136:                 {
  137:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  138:                     return;
  139:                 }
  140: 
  141:                 if (recherche_variable_partagee(s_etat_processus,
  142:                         (*(*s_etat_processus).pointeur_variable_courante).nom,
  143:                         (*(*s_etat_processus).pointeur_variable_courante)
  144:                         .variable_partagee, (*(*s_etat_processus)
  145:                         .pointeur_variable_courante).origine) == d_faux)
  146:                 {
  147:                     if (pthread_mutex_unlock(&((*(*s_etat_processus)
  148:                             .s_liste_variables_partagees).mutex)) != 0)
  149:                     {
  150:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  151:                         return;
  152:                     }
  153: 
  154:                     liberation(s_etat_processus, s_objet);
  155: 
  156:                     (*s_etat_processus).erreur_systeme = d_es;
  157:                     (*s_etat_processus).erreur_execution =
  158:                             d_ex_argument_invalide;
  159:                     return;
  160:                 }
  161: 
  162:                 if (((*(*(*s_etat_processus).s_liste_variables_partagees)
  163:                         .table[(*(*s_etat_processus)
  164:                         .s_liste_variables_partagees).position_variable].objet)
  165:                         .type != RPN) && ((*(*(*s_etat_processus)
  166:                         .s_liste_variables_partagees).table
  167:                         [(*(*s_etat_processus).s_liste_variables_partagees)
  168:                         .position_variable].objet).type != ADR))
  169:                 {
  170:                     if (pthread_mutex_unlock(&((*(*s_etat_processus)
  171:                             .s_liste_variables_partagees).mutex)) != 0)
  172:                     {
  173:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  174:                         return;
  175:                     }
  176: 
  177:                     liberation(s_etat_processus, s_objet);
  178: 
  179:                     (*s_etat_processus).erreur_execution =
  180:                             d_ex_argument_invalide;
  181:                     return;
  182:                 }
  183: 
  184:                 if ((s_copie = copie_objet(s_etat_processus,
  185:                         (*(*s_etat_processus)
  186:                         .s_liste_variables_partagees).table
  187:                         [(*(*s_etat_processus).s_liste_variables_partagees)
  188:                         .position_variable].objet, 'P')) == NULL)
  189:                 {
  190:                     if (pthread_mutex_unlock(&((*(*s_etat_processus)
  191:                             .s_liste_variables_partagees).mutex)) != 0)
  192:                     {
  193:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  194:                         return;
  195:                     }
  196: 
  197:                     (*s_etat_processus).erreur_systeme =
  198:                             d_es_allocation_memoire;
  199: 
  200:                     return;
  201:                 }
  202: 
  203:                 variable_partagee = d_vrai;
  204: 
  205:                 if (pthread_mutex_unlock(&((*(*s_etat_processus)
  206:                         .s_liste_variables_partagees).mutex)) != 0)
  207:                 {
  208:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  209:                     return;
  210:                 }
  211:             }
  212:             else
  213:             {
  214:                 if (((*(*(*s_etat_processus).pointeur_variable_courante).objet)
  215:                         .type != RPN) && ((*(*(*s_etat_processus)
  216:                         .pointeur_variable_courante).objet).type != ADR))
  217:                 {
  218:                     liberation(s_etat_processus, s_objet);
  219: 
  220:                     (*s_etat_processus).erreur_execution =
  221:                             d_ex_argument_invalide;
  222:                     return;
  223:                 }
  224:             }
  225:         }
  226:         else // Variable inexistante
  227:         {
  228:             liberation(s_etat_processus, s_objet);
  229: 
  230:             (*s_etat_processus).erreur_systeme = d_es;
  231:             (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
  232:             return;
  233:         }
  234:     }
  235: 
  236:     if ((s_argument_thread = malloc(sizeof(struct_descripteur_thread))) == NULL)
  237:     {
  238:         (*s_etat_processus).erreur_systeme = d_es_processus;
  239:         return;
  240:     }
  241: 
  242:     if (pipe((*s_argument_thread).pipe_erreurs) != 0)
  243:     {
  244:         (*s_etat_processus).erreur_systeme = d_es_processus;
  245:         return;
  246:     }
  247: 
  248:     if (pipe((*s_argument_thread).pipe_interruptions) != 0)
  249:     {
  250:         (*s_etat_processus).erreur_systeme = d_es_processus;
  251:         return;
  252:     }
  253: 
  254:     if (pipe((*s_argument_thread).pipe_nombre_interruptions_attente) != 0)
  255:     {
  256:         (*s_etat_processus).erreur_systeme = d_es_processus;
  257:         return;
  258:     }
  259: 
  260:     if (pipe((*s_argument_thread).pipe_objets) != 0)
  261:     {
  262:         (*s_etat_processus).erreur_systeme = d_es_processus;
  263:         return;
  264:     }
  265: 
  266:     if (pipe((*s_argument_thread).pipe_acquittement) != 0)
  267:     {
  268:         (*s_etat_processus).erreur_systeme = d_es_processus;
  269:         return;
  270:     }
  271: 
  272:     if (pipe((*s_argument_thread).pipe_nombre_objets_attente) != 0)
  273:     {
  274:         (*s_etat_processus).erreur_systeme = d_es_processus;
  275:         return;
  276:     }
  277: 
  278:     if (pipe((*s_argument_thread).pipe_injections) != 0)
  279:     {
  280:         (*s_etat_processus).erreur_systeme = d_es_processus;
  281:         return;
  282:     }
  283: 
  284:     if (pipe((*s_argument_thread).pipe_nombre_injections) != 0)
  285:     {
  286:         (*s_etat_processus).erreur_systeme = d_es_processus;
  287:         return;
  288:     }
  289: 
  290:     if ((s_nouvel_etat_processus = copie_etat_processus(s_etat_processus))
  291:             == NULL)
  292:     {
  293:         return;
  294:     }
  295: 
  296:     pthread_mutexattr_init(&attributs_mutex);
  297:     pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);
  298:     pthread_mutex_init(&((*s_argument_thread).mutex), &attributs_mutex);
  299:     pthread_mutexattr_destroy(&attributs_mutex);
  300: 
  301:     pthread_mutexattr_init(&attributs_mutex);
  302:     pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);
  303:     pthread_mutex_init(&((*s_argument_thread).mutex_nombre_references),
  304:             &attributs_mutex);
  305:     pthread_mutexattr_destroy(&attributs_mutex);
  306: 
  307:     (*s_argument_thread).processus_detache = d_faux;
  308:     (*s_argument_thread).thread_actif = d_faux;
  309:     (*s_argument_thread).thread_pere = pthread_self();
  310:     (*s_argument_thread).pid = getpid();
  311: 
  312:     (*s_nouvel_etat_processus).pipe_donnees =
  313:             (*s_argument_thread).pipe_objets[1];
  314:     (*s_nouvel_etat_processus).pipe_nombre_objets_attente =
  315:             (*s_argument_thread).pipe_nombre_objets_attente[1];
  316:     (*s_nouvel_etat_processus).pipe_interruptions =
  317:             (*s_argument_thread).pipe_interruptions[1];
  318:     (*s_nouvel_etat_processus).pipe_nombre_interruptions_attente =
  319:             (*s_argument_thread).pipe_nombre_interruptions_attente[1];
  320:     (*s_nouvel_etat_processus).pipe_injections =
  321:             (*s_argument_thread).pipe_injections[0];
  322:     (*s_nouvel_etat_processus).pipe_nombre_injections =
  323:             (*s_argument_thread).pipe_nombre_injections[0];
  324:     (*s_nouvel_etat_processus).pipe_acquittement =
  325:             (*s_argument_thread).pipe_acquittement[0];
  326:     (*s_nouvel_etat_processus).presence_pipes = d_vrai;
  327: 
  328:     (*s_nouvel_etat_processus).niveau_initial =
  329:             (*s_etat_processus).niveau_courant;
  330:     (*s_nouvel_etat_processus).debug_programme = d_faux;
  331:     (*s_nouvel_etat_processus).nombre_objets_injectes = 0;
  332:     (*s_nouvel_etat_processus).nombre_objets_envoyes_non_lus = 0;
  333:     (*s_nouvel_etat_processus).temps_maximal_cpu = 0;
  334:     (*s_nouvel_etat_processus).presence_fusible = d_faux;
  335:     (*s_nouvel_etat_processus).thread_fusible = 0;
  336: 
  337:     (*s_nouvel_etat_processus).pile_profilage = NULL;
  338:     (*s_nouvel_etat_processus).pile_profilage_fonctions = NULL;
  339: 
  340:     /*
  341:      * Lancement du thread fils et du thread de surveillance
  342:      */
  343: 
  344:     if (pthread_attr_init(&attributs) != 0)
  345:     {
  346:         (*s_etat_processus).erreur_systeme = d_es_processus;
  347:         return;
  348:     }
  349: 
  350:     if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
  351:     {
  352:         (*s_etat_processus).erreur_systeme = d_es_processus;
  353:         return;
  354:     }
  355: 
  356: #   ifdef SCHED_OTHER
  357:     if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
  358:     {
  359:         (*s_etat_processus).erreur_systeme = d_es_processus;
  360:         return;
  361:     }
  362: #   endif
  363: 
  364: #   ifdef PTHREAD_EXPLICIT_SCHED
  365:     if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)
  366:     {
  367:         (*s_etat_processus).erreur_systeme = d_es_processus;
  368:         return;
  369:     }
  370: #   endif
  371: 
  372: #   ifdef PTHREAD_SCOPE_SYSTEM
  373:     if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
  374:     {
  375:         (*s_etat_processus).erreur_systeme = d_es_processus;
  376:         return;
  377:     }
  378: #   endif
  379: 
  380:     /*
  381:      * Création de l'objet à retourner
  382:      */
  383: 
  384:     if ((s_objet_resultat = allocation(s_etat_processus, PRC)) == NULL)
  385:     {
  386:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  387:         return;
  388:     }
  389: 
  390:     (*((struct_processus_fils *) (*s_objet_resultat).objet)).thread
  391:             = s_argument_thread;
  392: 
  393:     (*(*((struct_processus_fils *) (*s_objet_resultat).objet)).thread)
  394:             .nombre_objets_dans_pipe = 0;
  395:     (*(*((struct_processus_fils *) (*s_objet_resultat).objet)).thread)
  396:             .nombre_interruptions_dans_pipe = 0;
  397:     (*(*((struct_processus_fils *) (*s_objet_resultat).objet)).thread)
  398:             .nombre_references = 1;
  399: 
  400:     // Lancement du thread fils
  401: 
  402:     (*s_argument_thread).s_nouvel_etat_processus = s_nouvel_etat_processus;
  403:     (*s_argument_thread).s_etat_processus = s_etat_processus;
  404: 
  405:     if (variable_partagee == d_vrai)
  406:     {
  407:         (*s_argument_thread).argument = s_copie;
  408:         (*s_argument_thread).destruction_objet = d_vrai;
  409:     }
  410:     else
  411:     {
  412:         (*s_argument_thread).argument = s_objet;
  413:         (*s_argument_thread).destruction_objet = d_faux;
  414:     }
  415: 
  416:     (*s_argument_thread).thread_actif = d_faux;
  417: 
  418:     if (pthread_create(&thread_id, &attributs, lancement_thread,
  419:             s_argument_thread) != 0)
  420:     {
  421:         (*s_etat_processus).erreur_systeme = d_es_processus;
  422:         return;
  423:     }
  424: 
  425:     attente.tv_sec = 0;
  426:     attente.tv_nsec = GRANULARITE_us * 1000;
  427: 
  428:     while((*s_argument_thread).thread_actif == d_faux)
  429:     {
  430:         scrutation_interruptions(s_etat_processus);
  431:         nanosleep(&attente, NULL);
  432:         INCR_GRANULARITE(attente.tv_nsec);
  433:     }
  434: 
  435:     if (pthread_attr_destroy(&attributs) != 0)
  436:     {
  437:         (*s_etat_processus).erreur_systeme = d_es_processus;
  438:         return;
  439:     }
  440: 
  441:     if (pthread_attr_init(&attributs) != 0)
  442:     {
  443:         (*s_etat_processus).erreur_systeme = d_es_processus;
  444:         return;
  445:     }
  446: 
  447:     if (pthread_attr_setdetachstate(&attributs,
  448:             PTHREAD_CREATE_DETACHED) != 0)
  449:     {
  450:         (*s_etat_processus).erreur_systeme = d_es_processus;
  451:         return;
  452:     }
  453: 
  454: #   ifdef SCHED_OTHER
  455:     if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
  456:     {
  457:         (*s_etat_processus).erreur_systeme = d_es_processus;
  458:         return;
  459:     }
  460: #   endif
  461: 
  462: #   ifdef PTHREAD_EXPLICIT_SCHED
  463:     if (pthread_attr_setinheritsched(&attributs,
  464:             PTHREAD_EXPLICIT_SCHED) != 0)
  465:     {
  466:         (*s_etat_processus).erreur_systeme = d_es_processus;
  467:         return;
  468:     }
  469: #   endif
  470: 
  471: #   ifdef PTHREAD_SCOPE_SYSTEM
  472:     if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
  473:     {
  474:         (*s_etat_processus).erreur_systeme = d_es_processus;
  475:         return;
  476:     }
  477: #   endif
  478: 
  479:     /*
  480:      * On copie l'objet plutôt que le pointeur car cet objet peut être
  481:      * accédé depuis deux threads distincts et aboutir à un blocage lors d'une
  482:      * copie.
  483:      */
  484: 
  485:     if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet_resultat, 'O'))
  486:             == NULL)
  487:     {
  488:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  489:         return;
  490:     }
  491: 
  492:     if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0)
  493:     {
  494:         pthread_mutex_unlock(&((*s_nouvel_etat_processus).mutex));
  495:         (*s_etat_processus).erreur_systeme = d_es_processus;
  496:         return;
  497:     }
  498: 
  499:     // Si le tid existe déjà  dans la pile des processus, il s'agit forcement
  500:     // d'un processus moribond. On attend donc qu'il soit effectivement
  501:     // libéré.
  502: 
  503:     do
  504:     {
  505:         l_element_courant = (struct_liste_chainee *)
  506:                 (*s_etat_processus).l_base_pile_processus;
  507:         drapeau = d_faux;
  508: 
  509:         attente.tv_sec = 0;
  510:         attente.tv_nsec = GRANULARITE_us * 1000;
  511: 
  512:         while(l_element_courant != NULL)
  513:         {
  514:             if (((*(*((struct_processus_fils *)
  515:                     (*(*l_element_courant).donnee).objet)).thread)
  516:                     .processus_detache == d_faux) &&
  517:                     ((*s_argument_thread).processus_detache == d_faux))
  518:             {
  519:                 if (pthread_equal((*(*((struct_processus_fils *)
  520:                         (*(*l_element_courant).donnee).objet)).thread)
  521:                         .tid, (*s_argument_thread).tid) != 0)
  522:                 {
  523:                     if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
  524:                     {
  525:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  526:                         return;
  527:                     }
  528: 
  529:                     scrutation_injection(s_etat_processus);
  530: 
  531:                     if ((*s_etat_processus).nombre_interruptions_non_affectees
  532:                             != 0)
  533:                     {
  534:                         affectation_interruptions_logicielles(s_etat_processus);
  535:                     }
  536: 
  537:                     if ((*s_etat_processus).nombre_interruptions_en_queue != 0)
  538:                     {
  539:                         traitement_interruptions_logicielles(s_etat_processus);
  540:                     }
  541: 
  542:                     nanosleep(&attente, NULL);
  543:                     INCR_GRANULARITE(attente.tv_nsec);
  544: 
  545:                     if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0)
  546:                     {
  547:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  548:                         return;
  549:                     }
  550: 
  551:                     drapeau = d_vrai;
  552:                     break;
  553:                 }
  554:             }
  555: 
  556:             scrutation_interruptions(s_etat_processus);
  557:             l_element_courant = (*l_element_courant).suivant;
  558:         }
  559:     } while(drapeau == d_vrai);
  560: 
  561:     if (empilement(s_etat_processus,
  562:             (struct_liste_chainee **) &((*s_etat_processus)
  563:             .l_base_pile_processus), s_objet_systeme) == d_erreur)
  564:     {
  565:         pthread_mutex_unlock(&((*s_etat_processus).mutex));
  566:         return;
  567:     }
  568: 
  569:     if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
  570:     {
  571:         (*s_etat_processus).erreur_systeme = d_es_processus;
  572:         return;
  573:     }
  574: 
  575:     if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
  576:             s_objet_resultat) == d_erreur)
  577:     {
  578:         return;
  579:     }
  580: 
  581:     if (pthread_mutex_lock(&(*s_argument_thread).mutex) != 0)
  582:     {
  583:         (*s_etat_processus).erreur_systeme = d_es_processus;
  584:         return;
  585:     }
  586: 
  587:     if ((*s_argument_thread).thread_actif == d_faux)
  588:     {
  589:         // Le thread n'existe plus.
  590: 
  591:         pthread_join((*s_argument_thread).tid, NULL);
  592:         pthread_mutex_unlock(&(*s_argument_thread).mutex);
  593:         (*s_etat_processus).erreur_systeme = d_es_processus;
  594:         return;
  595:     }
  596: 
  597:     if (pthread_mutex_unlock(&(*s_argument_thread).mutex) != 0)
  598:     {
  599:         (*s_etat_processus).erreur_systeme = d_es_processus;
  600:         return;
  601:     }
  602: 
  603:     // Lancement du thread de surveillance
  604: 
  605:     if (pthread_create(&thread_surveillance, &attributs,
  606:             surveillance_processus, s_argument_thread) != 0)
  607:     {
  608:         (*s_etat_processus).erreur_systeme = d_es_processus;
  609:         return;
  610:     }
  611: 
  612:     if (pthread_attr_destroy(&attributs) != 0)
  613:     {
  614:         (*s_etat_processus).erreur_systeme = d_es_processus;
  615:         return;
  616:     }
  617: 
  618:     // Le fils peut être présent sans être en attente du signal de départ.
  619: 
  620:     if (envoi_signal_thread((*s_argument_thread).tid, rpl_sigstart) != 0)
  621:     {
  622:         (*s_etat_processus).erreur_systeme = d_es_processus;
  623:         return;
  624:     }
  625: 
  626:     return;
  627: }
  628: 
  629: 
  630: /*
  631: ================================================================================
  632:   Fonction 'sqlconnect'
  633: ================================================================================
  634:   Entrées :
  635: --------------------------------------------------------------------------------
  636:   Sorties :
  637: --------------------------------------------------------------------------------
  638:   Effets de bord : néant
  639: ================================================================================
  640: */
  641: 
  642: void
  643: instruction_sqlconnect(struct_processus *s_etat_processus)
  644: {
  645:     struct_objet            *s_objet_argument;
  646:     struct_objet            *s_objet_resultat;
  647:     struct_objet            *s_objet_systeme;
  648: 
  649:     (*s_etat_processus).erreur_execution = d_ex;
  650: 
  651:     if ((*s_etat_processus).affichage_arguments == 'Y')
  652:     {
  653:         printf("\n  SQLCONNECT ");
  654: 
  655:         if ((*s_etat_processus).langue == 'F')
  656:         {
  657:             printf("(connexion à une base de données SQL)\n\n");
  658:         }
  659:         else
  660:         {
  661:             printf("(connect to SQL database)\n\n");
  662:         }
  663: 
  664:         printf("    1: %s\n", d_LST);
  665:         printf("->  1: %s\n\n", d_SQL);
  666: 
  667:         if ((*s_etat_processus).langue == 'F')
  668:         {
  669:             printf("  Utilisation :\n\n");
  670:         }
  671:         else
  672:         {
  673:             printf("  Usage:\n\n");
  674:         }
  675: 
  676:         printf("    { \"mysql\" \"server\" \"database\" "
  677:                 "\"user\" \"password\" } SQLCONNECT\n");
  678:         printf("    { \"postgresql:iso-8859-1\" \"server\" "
  679:                 "\"database\" \"user\" \"password\" port }\n");
  680:         printf("          SQLCONNECT\n");
  681: 
  682:         return;
  683:     }
  684:     else if ((*s_etat_processus).test_instruction == 'Y')
  685:     {
  686:         (*s_etat_processus).nombre_arguments = -1;
  687:         return;
  688:     }
  689:     
  690:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
  691:     {
  692:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
  693:         {
  694:             return;
  695:         }
  696:     }
  697: 
  698:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
  699:             &s_objet_argument) == d_erreur)
  700:     {
  701:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
  702:         return;
  703:     }
  704: 
  705:     if ((*s_objet_argument).type == LST)
  706:     {
  707:         if ((s_objet_resultat = parametres_sql(s_etat_processus,
  708:                 s_objet_argument)) == NULL)
  709:         {
  710:             liberation(s_etat_processus, s_objet_argument);
  711:             return;
  712:         }
  713: 
  714:         if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet_resultat,
  715:                 'O')) == NULL)
  716:         {
  717:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  718:             return;
  719:         }
  720: 
  721:         if (empilement(s_etat_processus,
  722:                 (struct_liste_chainee **) &((*s_etat_processus)
  723:                 .s_connecteurs_sql), s_objet_systeme) == d_erreur)
  724:         {
  725:             return;
  726:         }
  727: 
  728:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
  729:                 s_objet_resultat) == d_erreur)
  730:         {
  731:             return;
  732:         }
  733:     }
  734:     else
  735:     {
  736:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
  737: 
  738:         liberation(s_etat_processus, s_objet_argument);
  739:         return;
  740:     }
  741: 
  742:     liberation(s_etat_processus, s_objet_argument);
  743:     return;
  744: }
  745: 
  746: 
  747: /*
  748: ================================================================================
  749:   Fonction 'sqldisconnect'
  750: ================================================================================
  751:   Entrées :
  752: --------------------------------------------------------------------------------
  753:   Sorties :
  754: --------------------------------------------------------------------------------
  755:   Effets de bord : néant
  756: ================================================================================
  757: */
  758: 
  759: void
  760: instruction_sqldisconnect(struct_processus *s_etat_processus)
  761: {
  762:     logical1                drapeau;
  763: 
  764:     struct_liste_chainee    *l_element_courant;
  765:     struct_liste_chainee    *l_element_precedent;
  766: 
  767:     struct_objet            *s_objet;
  768: 
  769:     (*s_etat_processus).erreur_execution = d_ex;
  770: 
  771:     if ((*s_etat_processus).affichage_arguments == 'Y')
  772:     {
  773:         printf("\n  SQLDISCONNECT ");
  774: 
  775:         if ((*s_etat_processus).langue == 'F')
  776:         {
  777:             printf("(déconnexion d'une base de donnée SQL)\n\n");
  778:         }
  779:         else
  780:         {
  781:             printf("(disconnection from SQL database)\n\n");
  782:         }
  783: 
  784:         printf("    1: %s\n", d_SQL);
  785:         return;
  786:     }
  787:     else if ((*s_etat_processus).test_instruction == 'Y')
  788:     {
  789:         (*s_etat_processus).nombre_arguments = -1;
  790:         return;
  791:     }
  792:     
  793:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
  794:     {
  795:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
  796:         {
  797:             return;
  798:         }
  799:     }
  800: 
  801:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
  802:             &s_objet) == d_erreur)
  803:     {
  804:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
  805:         return;
  806:     }
  807: 
  808:     if ((*s_objet).type == SQL)
  809:     {
  810:         if (((*((struct_connecteur_sql *) (*s_objet).objet)).pid !=
  811:                 getpid()) || (pthread_equal((*((struct_connecteur_sql *)
  812:                 (*s_objet).objet)).tid, pthread_self()) == 0))
  813:         {
  814:             (*s_etat_processus).erreur_execution = d_ex_fichier_hors_contexte;
  815: 
  816:             liberation(s_etat_processus, s_objet);
  817:             return;
  818:         }
  819: 
  820:         l_element_courant = (*s_etat_processus).s_connecteurs_sql;
  821:         l_element_precedent = NULL;
  822: 
  823:         while(l_element_courant != NULL)
  824:         {
  825:             if (((*((struct_connecteur_sql *) (*(*l_element_courant).donnee)
  826:                     .objet)).pid == getpid()) && (pthread_equal(
  827:                     (*((struct_connecteur_sql *) (*(*l_element_courant).donnee)
  828:                     .objet)).tid, pthread_self()) != 0) &&
  829:                     (strcmp((*((struct_connecteur_sql *) (*(*l_element_courant)
  830:                     .donnee).objet)).type, (*((struct_connecteur_sql *)
  831:                     (*s_objet).objet)).type) == 0))
  832:             {
  833:                 if (strcmp((*((struct_connecteur_sql *) (*s_objet).objet)).type,
  834:                         "MYSQL") == 0)
  835:                 {
  836: #                   ifdef MYSQL_SUPPORT
  837: 
  838:                     if ((*((struct_connecteur_sql *) (*(*l_element_courant)
  839:                             .donnee).objet)).descripteur.mysql ==
  840:                             (*((struct_connecteur_sql *) (*s_objet).objet))
  841:                             .descripteur.mysql)
  842:                     {
  843:                         drapeau = d_vrai;
  844:                     }
  845:                     else
  846:                     {
  847:                         drapeau = d_faux;
  848:                     }
  849: 
  850: #                   else
  851: 
  852:                     if ((*s_etat_processus).langue == 'F')
  853:                     {
  854:                         printf("+++Attention : Support de MySQL "
  855:                                 "non compilé !\n");
  856:                     }
  857:                     else
  858:                     {
  859:                         printf("+++Warning : MySQL support not available !\n");
  860:                     }
  861: 
  862:                     fflush(stdout);
  863: 
  864:                     drapeau = d_faux;
  865: #                   endif
  866:                 }
  867:                 else if (strcmp((*((struct_connecteur_sql *) (*s_objet).objet))
  868:                         .type, "POSTGRESQL") == 0)
  869:                 {
  870: #                   ifdef POSTGRESQL_SUPPORT
  871: 
  872:                     if ((*((struct_connecteur_sql *) (*(*l_element_courant)
  873:                             .donnee).objet)).descripteur.postgresql ==
  874:                             (*((struct_connecteur_sql *) (*s_objet).objet))
  875:                             .descripteur.postgresql)
  876:                     {
  877:                         drapeau = d_vrai;
  878:                     }
  879:                     else
  880:                     {
  881:                         drapeau = d_faux;
  882:                     }
  883: 
  884: #                   else
  885: 
  886:                     if ((*s_etat_processus).langue == 'F')
  887:                     {
  888:                         printf("+++Attention : Support de PostgreSQL "
  889:                                 "non compilé !\n");
  890:                     }
  891:                     else
  892:                     {
  893:                         printf("+++Warning : PostgreSQL support "
  894:                                 "not available !\n");
  895:                     }
  896: 
  897:                     fflush(stdout);
  898: 
  899:                     drapeau = d_faux;
  900: #                   endif
  901:                 }
  902:                 else
  903:                 {
  904:                     BUG(1, printf("SQL type '%s' not allowed!",
  905:                             (*((struct_connecteur_sql *) (*s_objet).objet))
  906:                             .type));
  907:                     return;
  908:                 }
  909: 
  910:                 if (drapeau == d_vrai)
  911:                 {
  912:                     if (l_element_precedent == NULL)
  913:                     {
  914:                         (*s_etat_processus).s_connecteurs_sql =
  915:                                 (*l_element_courant).suivant;
  916:                     }
  917:                     else if ((*l_element_courant).suivant == NULL)
  918:                     {
  919:                         (*l_element_precedent).suivant = NULL;
  920:                     }
  921:                     else
  922:                     {
  923:                         (*l_element_precedent).suivant =
  924:                                 (*l_element_courant).suivant;
  925:                     }
  926: 
  927:                     liberation(s_etat_processus, (*l_element_courant).donnee);
  928:                     free(l_element_courant);
  929: 
  930:                     break;
  931:                 }
  932:             }
  933: 
  934:             l_element_precedent = l_element_courant;
  935:             l_element_courant = (*l_element_courant).suivant;
  936:         }
  937: 
  938:         sqlclose(s_objet);
  939:     }
  940:     else
  941:     {
  942:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
  943: 
  944:         liberation(s_etat_processus, s_objet);
  945:         return;
  946:     }
  947: 
  948:     liberation(s_etat_processus, s_objet);
  949:     return;
  950: }
  951: 
  952: 
  953: /*
  954: ================================================================================
  955:   Fonction 'smphrincr'
  956: ================================================================================
  957:   Entrées :
  958: --------------------------------------------------------------------------------
  959:   Sorties :
  960: --------------------------------------------------------------------------------
  961:   Effets de bord : néant
  962: ================================================================================
  963: */
  964: 
  965: void
  966: instruction_smphrincr(struct_processus *s_etat_processus)
  967: {
  968:     struct_objet                *s_objet_argument;
  969: 
  970:     (*s_etat_processus).erreur_execution = d_ex;
  971: 
  972:     if ((*s_etat_processus).affichage_arguments == 'Y')
  973:     {
  974:         printf("\n  SMPHRINCR ");
  975: 
  976:         if ((*s_etat_processus).langue == 'F')
  977:         {
  978:             printf("(incrémentation du sémaphore)\n\n");
  979:         }
  980:         else
  981:         {
  982:             printf("(semaphore incrementation)\n\n");
  983:         }
  984: 
  985:         printf("    1: %s\n", d_SPH);
  986:         return;
  987:     }
  988:     else if ((*s_etat_processus).test_instruction == 'Y')
  989:     {
  990:         (*s_etat_processus).nombre_arguments = -1;
  991:         return;
  992:     }
  993:     
  994:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
  995:     {
  996:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
  997:         {
  998:             return;
  999:         }
 1000:     }
 1001: 
 1002:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1003:             &s_objet_argument) == d_erreur)
 1004:     {
 1005:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1006:         return;
 1007:     }
 1008: 
 1009:     if ((*s_objet_argument).type == SPH)
 1010:     {
 1011:         if (sem_post((*((struct_semaphore *) (*s_objet_argument).objet))
 1012:                 .semaphore) != 0)
 1013:         {
 1014:             (*s_etat_processus).erreur_execution = d_ex_semaphore;
 1015: 
 1016:             liberation(s_etat_processus, s_objet_argument);
 1017:             return;
 1018:         }
 1019: 
 1020:         liberation(s_etat_processus, s_objet_argument);
 1021:     }
 1022:     else
 1023:     {
 1024:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1025: 
 1026:         liberation(s_etat_processus, s_objet_argument);
 1027:         return;
 1028:     }
 1029: 
 1030:     return;
 1031: }
 1032: 
 1033: 
 1034: /*
 1035: ================================================================================
 1036:   Fonction 'smphrdecr'
 1037: ================================================================================
 1038:   Entrées :
 1039: --------------------------------------------------------------------------------
 1040:   Sorties :
 1041: --------------------------------------------------------------------------------
 1042:   Effets de bord : néant
 1043: ================================================================================
 1044: */
 1045: 
 1046: void
 1047: instruction_smphrdecr(struct_processus *s_etat_processus)
 1048: {
 1049:     struct_objet                *s_objet_argument;
 1050: 
 1051:     unsigned char               *tampon;
 1052: 
 1053:     (*s_etat_processus).erreur_execution = d_ex;
 1054: 
 1055:     if ((*s_etat_processus).affichage_arguments == 'Y')
 1056:     {
 1057:         printf("\n  SMPHRDECR ");
 1058: 
 1059:         if ((*s_etat_processus).langue == 'F')
 1060:         {
 1061:             printf("(decrémentation du sémaphore)\n\n");
 1062:         }
 1063:         else
 1064:         {
 1065:             printf("(semaphore decrementation)\n\n");
 1066:         }
 1067: 
 1068:         printf("    1: %s\n", d_SPH);
 1069:         return;
 1070:     }
 1071:     else if ((*s_etat_processus).test_instruction == 'Y')
 1072:     {
 1073:         (*s_etat_processus).nombre_arguments = -1;
 1074:         return;
 1075:     }
 1076:     
 1077:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
 1078:     {
 1079:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
 1080:         {
 1081:             return;
 1082:         }
 1083:     }
 1084: 
 1085:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1086:             &s_objet_argument) == d_erreur)
 1087:     {
 1088:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1089:         return;
 1090:     }
 1091: 
 1092:     if ((*s_objet_argument).type == SPH)
 1093:     {
 1094:         if ((*s_etat_processus).profilage == d_vrai)
 1095:         {
 1096:             if ((tampon = formateur(s_etat_processus, 0, s_objet_argument))
 1097:                     == NULL)
 1098:             {
 1099:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1100:                 return;
 1101:             }
 1102: 
 1103:             profilage(s_etat_processus, tampon);
 1104:             free(tampon);
 1105: 
 1106:             if ((*s_etat_processus).erreur_systeme != d_es)
 1107:             {
 1108:                 return;
 1109:             }
 1110:         }
 1111: 
 1112: #       ifndef SEMAPHORES_NOMMES
 1113:             if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
 1114: #       else
 1115:             if (sem_post((*s_etat_processus).semaphore_fork) != 0)
 1116: #       endif
 1117:         {
 1118:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1119:             return;
 1120:         }
 1121: 
 1122:         while(sem_wait((*((struct_semaphore *) (*s_objet_argument).objet))
 1123:                 .semaphore) == -1)
 1124:         {
 1125:             if (errno != EINTR)
 1126:             {
 1127: #               ifndef SEMAPHORES_NOMMES
 1128:                     sem_post(&((*s_etat_processus).semaphore_fork));
 1129: #               else
 1130:                     sem_post((*s_etat_processus).semaphore_fork);
 1131: #               endif
 1132: 
 1133:                 (*s_etat_processus).erreur_execution = d_ex_semaphore;
 1134: 
 1135:                 if ((*s_etat_processus).profilage == d_vrai)
 1136:                 {
 1137:                     profilage(s_etat_processus, NULL);
 1138:                 }
 1139: 
 1140:                 liberation(s_etat_processus, s_objet_argument);
 1141:                 return;
 1142:             }
 1143:         }
 1144: 
 1145: #       ifndef SEMAPHORES_NOMMES
 1146:             while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 1147: #       else
 1148:             while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
 1149: #       endif
 1150:         {
 1151:             if (errno != EINTR)
 1152:             {
 1153:                 if ((*s_etat_processus).profilage == d_vrai)
 1154:                 {
 1155:                     profilage(s_etat_processus, NULL);
 1156:                 }
 1157: 
 1158:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1159:                 return;
 1160:             }
 1161:         }
 1162: 
 1163:         if ((*s_etat_processus).profilage == d_vrai)
 1164:         {
 1165:             profilage(s_etat_processus, NULL);
 1166:         }
 1167: 
 1168:         liberation(s_etat_processus, s_objet_argument);
 1169:     }
 1170:     else
 1171:     {
 1172:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1173: 
 1174:         liberation(s_etat_processus, s_objet_argument);
 1175:         return;
 1176:     }
 1177: 
 1178:     return;
 1179: }
 1180: 
 1181: 
 1182: /*
 1183: ================================================================================
 1184:   Fonction 'smphrtrydecr'
 1185: ================================================================================
 1186:   Entrées :
 1187: --------------------------------------------------------------------------------
 1188:   Sorties :
 1189: --------------------------------------------------------------------------------
 1190:   Effets de bord : néant
 1191: ================================================================================
 1192: */
 1193: 
 1194: void
 1195: instruction_smphrtrydecr(struct_processus *s_etat_processus)
 1196: {
 1197:     struct_objet                *s_objet_argument;
 1198:     struct_objet                *s_objet_resultat;
 1199: 
 1200:     unsigned char               *tampon;
 1201: 
 1202:     (*s_etat_processus).erreur_execution = d_ex;
 1203: 
 1204:     if ((*s_etat_processus).affichage_arguments == 'Y')
 1205:     {
 1206:         printf("\n  SMPHRTRYDECR ");
 1207: 
 1208:         if ((*s_etat_processus).langue == 'F')
 1209:         {
 1210:             printf("(essai de decrémentation du sémaphore)\n\n");
 1211:         }
 1212:         else
 1213:         {
 1214:             printf("(try to decremente semaphore)\n\n");
 1215:         }
 1216: 
 1217:         printf("    1: %s\n", d_SPH);
 1218:         printf("->  1: %s\n", d_INT);
 1219:         return;
 1220:     }
 1221:     else if ((*s_etat_processus).test_instruction == 'Y')
 1222:     {
 1223:         (*s_etat_processus).nombre_arguments = -1;
 1224:         return;
 1225:     }
 1226:     
 1227:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
 1228:     {
 1229:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
 1230:         {
 1231:             return;
 1232:         }
 1233:     }
 1234: 
 1235:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1236:             &s_objet_argument) == d_erreur)
 1237:     {
 1238:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1239:         return;
 1240:     }
 1241: 
 1242:     if ((*s_objet_argument).type == SPH)
 1243:     {
 1244:         if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL)
 1245:         {
 1246:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1247:             return;
 1248:         }
 1249: 
 1250:         if ((*s_etat_processus).profilage == d_vrai)
 1251:         {
 1252:             if ((tampon = formateur(s_etat_processus, 0, s_objet_argument))
 1253:                     == NULL)
 1254:             {
 1255:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1256:                 return;
 1257:             }
 1258: 
 1259:             profilage(s_etat_processus, tampon);
 1260:             free(tampon);
 1261: 
 1262:             if ((*s_etat_processus).erreur_systeme != d_es)
 1263:             {
 1264:                 return;
 1265:             }
 1266:         }
 1267: 
 1268: #       ifndef SEMAPHORES_NOMMES
 1269:             if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
 1270: #       else
 1271:             if (sem_post((*s_etat_processus).semaphore_fork) != 0)
 1272: #       endif
 1273:         {
 1274:             if ((*s_etat_processus).profilage == d_vrai)
 1275:             {
 1276:                 profilage(s_etat_processus, NULL);
 1277:             }
 1278: 
 1279:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1280:             return;
 1281:         }
 1282: 
 1283:         (*((integer8 *) (*s_objet_resultat).objet)) = 0;
 1284: 
 1285:         while(sem_trywait((*((struct_semaphore *) (*s_objet_argument).objet))
 1286:                 .semaphore) == -1)
 1287:         {
 1288:             switch(errno)
 1289:             {
 1290:                 case EINTR :
 1291:                 {
 1292:                     break;
 1293:                 }
 1294: 
 1295:                 case EINVAL :
 1296:                 {
 1297:                     (*s_etat_processus).erreur_execution = d_ex_semaphore;
 1298: 
 1299:                     if ((*s_etat_processus).profilage == d_vrai)
 1300:                     {
 1301:                         profilage(s_etat_processus, NULL);
 1302:                     }
 1303: 
 1304:                     liberation(s_etat_processus, s_objet_argument);
 1305:                     return;
 1306:                 }
 1307: 
 1308:                 case EAGAIN :
 1309:                 {
 1310:                     (*((integer8 *) (*s_objet_resultat).objet)) = -1;
 1311:                     break;
 1312:                 }
 1313:             }
 1314: 
 1315:             if ((*((integer8 *) (*s_objet_resultat).objet)) != 0)
 1316:             {
 1317:                 break;
 1318:             }
 1319:         }
 1320: 
 1321: #       ifndef SEMAPHORES_NOMMES
 1322:             while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
 1323: #       else
 1324:             while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
 1325: #       endif
 1326:         {
 1327:             if (errno != EINTR)
 1328:             {
 1329:                 if ((*s_etat_processus).profilage == d_vrai)
 1330:                 {
 1331:                     profilage(s_etat_processus, NULL);
 1332:                 }
 1333: 
 1334:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1335:                 return;
 1336:             }
 1337:         }
 1338: 
 1339:         if ((*s_etat_processus).profilage == d_vrai)
 1340:         {
 1341:             profilage(s_etat_processus, NULL);
 1342:         }
 1343: 
 1344:         liberation(s_etat_processus, s_objet_argument);
 1345:     }
 1346:     else
 1347:     {
 1348:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1349: 
 1350:         liberation(s_etat_processus, s_objet_argument);
 1351:         return;
 1352:     }
 1353: 
 1354:     return;
 1355: }
 1356: 
 1357: 
 1358: /*
 1359: ================================================================================
 1360:   Fonction 'smphrgetv'
 1361: ================================================================================
 1362:   Entrées :
 1363: --------------------------------------------------------------------------------
 1364:   Sorties :
 1365: --------------------------------------------------------------------------------
 1366:   Effets de bord : néant
 1367: ================================================================================
 1368: */
 1369: 
 1370: void
 1371: instruction_smphrgetv(struct_processus *s_etat_processus)
 1372: {
 1373:     int                         valeur;
 1374: 
 1375:     struct_objet                *s_objet_argument;
 1376:     struct_objet                *s_objet_resultat;
 1377: 
 1378:     (*s_etat_processus).erreur_execution = d_ex;
 1379: 
 1380:     if ((*s_etat_processus).affichage_arguments == 'Y')
 1381:     {
 1382:         printf("\n  SMPHRGETV ");
 1383: 
 1384:         if ((*s_etat_processus).langue == 'F')
 1385:         {
 1386:             printf("(valeur du sémaphore)\n\n");
 1387:         }
 1388:         else
 1389:         {
 1390:             printf("(semaphore value)\n\n");
 1391:         }
 1392: 
 1393:         printf("    1: %s\n", d_SPH);
 1394:         return;
 1395:     }
 1396:     else if ((*s_etat_processus).test_instruction == 'Y')
 1397:     {
 1398:         (*s_etat_processus).nombre_arguments = -1;
 1399:         return;
 1400:     }
 1401:     
 1402:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
 1403:     {
 1404:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
 1405:         {
 1406:             return;
 1407:         }
 1408:     }
 1409: 
 1410:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1411:             &s_objet_argument) == d_erreur)
 1412:     {
 1413:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1414:         return;
 1415:     }
 1416: 
 1417:     if ((*s_objet_argument).type == SPH)
 1418:     {
 1419:         if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL)
 1420:         {
 1421:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1422: 
 1423:             liberation(s_etat_processus, s_objet_argument);
 1424:             return;
 1425:         }
 1426: 
 1427:         if (sem_getvalue((*((struct_semaphore *) (*s_objet_argument).objet))
 1428:                 .semaphore, &valeur) != 0)
 1429:         {
 1430:             (*s_etat_processus).erreur_execution = d_ex_semaphore;
 1431: 
 1432:             liberation(s_etat_processus, s_objet_argument);
 1433:             return;
 1434:         }
 1435: 
 1436:         (*((integer8 *) (*s_objet_resultat).objet)) = valeur;
 1437: 
 1438:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1439:                 s_objet_resultat) == d_erreur)
 1440:         {
 1441:             return;
 1442:         }
 1443: 
 1444:         liberation(s_etat_processus, s_objet_argument);
 1445:     }
 1446:     else
 1447:     {
 1448:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1449: 
 1450:         liberation(s_etat_processus, s_objet_argument);
 1451:         return;
 1452:     }
 1453: 
 1454:     return;
 1455: }
 1456: 
 1457: 
 1458: /*
 1459: ================================================================================
 1460:   Fonction 'svl'
 1461: ================================================================================
 1462:   Entrées :
 1463: --------------------------------------------------------------------------------
 1464:   Sorties :
 1465: --------------------------------------------------------------------------------
 1466:   Effets de bord : néant
 1467: ================================================================================
 1468: */
 1469: 
 1470: void
 1471: instruction_svl(struct_processus *s_etat_processus)
 1472: {
 1473:     struct_objet                *s_objet_argument;
 1474:     struct_objet                *s_objet_resultat;
 1475: 
 1476:     (*s_etat_processus).erreur_execution = d_ex;
 1477: 
 1478:     if ((*s_etat_processus).affichage_arguments == 'Y')
 1479:     {
 1480:         printf("\n  SVL ");
 1481: 
 1482:         if ((*s_etat_processus).langue == 'F')
 1483:         {
 1484:             printf("(valeurs singulières)\n\n");
 1485:         }
 1486:         else
 1487:         {
 1488:             printf("(singular values)\n\n");
 1489:         }
 1490: 
 1491:         printf("    1: %s, %s, %s\n", d_MIN, d_MRL, d_MCX);
 1492:         printf("->  1: %s\n", d_VRL);
 1493:         return;
 1494:     }
 1495:     else if ((*s_etat_processus).test_instruction == 'Y')
 1496:     {
 1497:         (*s_etat_processus).nombre_arguments = -1;
 1498:         return;
 1499:     }
 1500:     
 1501:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
 1502:     {
 1503:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
 1504:         {
 1505:             return;
 1506:         }
 1507:     }
 1508: 
 1509:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1510:             &s_objet_argument) == d_erreur)
 1511:     {
 1512:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1513:         return;
 1514:     }
 1515: 
 1516:     if (((*s_objet_argument).type == MIN) ||
 1517:             ((*s_objet_argument).type == MRL) ||
 1518:             ((*s_objet_argument).type == MCX))
 1519:     {
 1520:         if ((s_objet_resultat = allocation(s_etat_processus, VRL)) == NULL)
 1521:         {
 1522:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1523:             return;
 1524:         }
 1525: 
 1526:         valeurs_singulieres(s_etat_processus, (*s_objet_argument).objet,
 1527:                 NULL, (*s_objet_resultat).objet, NULL);
 1528: 
 1529:         if ((*s_etat_processus).erreur_systeme != d_es)
 1530:         {
 1531:             return;
 1532:         }
 1533: 
 1534:         if (((*s_etat_processus).erreur_execution != d_ex) ||
 1535:                 ((*s_etat_processus).exception != d_ep))
 1536:         {
 1537:             liberation(s_etat_processus, s_objet_resultat);
 1538:             liberation(s_etat_processus, s_objet_argument);
 1539:             return;
 1540:         }
 1541: 
 1542:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1543:                 s_objet_resultat) == d_erreur)
 1544:         {
 1545:             return;
 1546:         }
 1547:     }
 1548:     else
 1549:     {
 1550:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1551: 
 1552:         liberation(s_etat_processus, s_objet_argument);
 1553:         return;
 1554:     }
 1555: 
 1556:     liberation(s_etat_processus, s_objet_argument);
 1557: 
 1558:     return;
 1559: }
 1560: 
 1561: 
 1562: /*
 1563: ================================================================================
 1564:   Fonction 'svd'
 1565: ================================================================================
 1566:   Entrées :
 1567: --------------------------------------------------------------------------------
 1568:   Sorties :
 1569: --------------------------------------------------------------------------------
 1570:   Effets de bord : néant
 1571: ================================================================================
 1572: */
 1573: 
 1574: void
 1575: instruction_svd(struct_processus *s_etat_processus)
 1576: {
 1577:     struct_objet                *s_objet_argument;
 1578:     struct_objet                *s_objet_resultat_1;
 1579:     struct_objet                *s_objet_resultat_2;
 1580:     struct_objet                *s_objet_resultat_3;
 1581: 
 1582:     struct_vecteur              s_vecteur;
 1583: 
 1584:     unsigned long               i;
 1585:     unsigned long               j;
 1586: 
 1587:     (*s_etat_processus).erreur_execution = d_ex;
 1588: 
 1589:     if ((*s_etat_processus).affichage_arguments == 'Y')
 1590:     {
 1591:         printf("\n  SVD ");
 1592: 
 1593:         if ((*s_etat_processus).langue == 'F')
 1594:         {
 1595:             printf("(décomposition en valeurs singulières)\n\n");
 1596:         }
 1597:         else
 1598:         {
 1599:             printf("(singular value decomposition)\n\n");
 1600:         }
 1601: 
 1602:         printf("    1: %s, %s, %s\n", d_MIN, d_MRL, d_MCX);
 1603:         printf("->  3: %s, %s\n", d_MRL, d_MCX);
 1604:         printf("    2: %s, %s\n", d_MRL, d_MCX);
 1605:         printf("    1: %s\n", d_VRL);
 1606:         return;
 1607:     }
 1608:     else if ((*s_etat_processus).test_instruction == 'Y')
 1609:     {
 1610:         (*s_etat_processus).nombre_arguments = -1;
 1611:         return;
 1612:     }
 1613:     
 1614:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
 1615:     {
 1616:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
 1617:         {
 1618:             return;
 1619:         }
 1620:     }
 1621: 
 1622:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1623:             &s_objet_argument) == d_erreur)
 1624:     {
 1625:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1626:         return;
 1627:     }
 1628: 
 1629:     if (((*s_objet_argument).type == MIN) ||
 1630:             ((*s_objet_argument).type == MRL))
 1631:     {
 1632:         if ((s_objet_resultat_1 = allocation(s_etat_processus, MRL)) == NULL)
 1633:         {
 1634:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1635:             return;
 1636:         }
 1637: 
 1638:         if ((s_objet_resultat_2 = allocation(s_etat_processus, MRL)) == NULL)
 1639:         {
 1640:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1641:             return;
 1642:         }
 1643: 
 1644:         if ((s_objet_resultat_3 = allocation(s_etat_processus, MRL)) == NULL)
 1645:         {
 1646:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1647:             return;
 1648:         }
 1649: 
 1650:         valeurs_singulieres(s_etat_processus, (*s_objet_argument).objet,
 1651:                 (*s_objet_resultat_3).objet, &s_vecteur,
 1652:                 (*s_objet_resultat_1).objet);
 1653: 
 1654:         if ((*s_etat_processus).erreur_systeme != d_es)
 1655:         {
 1656:             return;
 1657:         }
 1658: 
 1659:         if (((*s_etat_processus).erreur_execution != d_ex) ||
 1660:                 ((*s_etat_processus).exception != d_ep))
 1661:         {
 1662:             liberation(s_etat_processus, s_objet_resultat_1);
 1663:             liberation(s_etat_processus, s_objet_resultat_2);
 1664:             liberation(s_etat_processus, s_objet_resultat_3);
 1665:             liberation(s_etat_processus, s_objet_argument);
 1666:             return;
 1667:         }
 1668: 
 1669:         (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_colonnes =
 1670:                 (*((struct_matrice *) (*s_objet_argument).objet))
 1671:                 .nombre_colonnes;
 1672:         (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_lignes =
 1673:                 (*((struct_matrice *) (*s_objet_argument).objet))
 1674:                 .nombre_lignes;
 1675: 
 1676:         if (((*((struct_matrice *) (*s_objet_resultat_2).objet)).tableau =
 1677:                 malloc((*((struct_matrice *) (*s_objet_resultat_2).objet))
 1678:                 .nombre_lignes * sizeof(real8 *))) == NULL)
 1679:         {
 1680:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1681:             return;
 1682:         }
 1683: 
 1684:         for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat_2).objet))
 1685:                 .nombre_lignes; i++)
 1686:         {
 1687:             if ((((real8 **) (*((struct_matrice *) (*s_objet_resultat_2)
 1688:                     .objet)).tableau)[i] = malloc((*((struct_matrice *)
 1689:                     (*s_objet_resultat_2).objet)).nombre_colonnes *
 1690:                     sizeof(real8 *))) == NULL)
 1691:             {
 1692:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1693:                 return;
 1694:             }
 1695: 
 1696:             for(j = 0; j < (*((struct_matrice *) (*s_objet_resultat_2).objet))
 1697:                     .nombre_colonnes; j++)
 1698:             {
 1699:                 ((real8 **) (*((struct_matrice *) (*s_objet_resultat_2)
 1700:                         .objet)).tableau)[i][j] = 0;
 1701:             }
 1702:         }
 1703: 
 1704:         for(i = 0; i < s_vecteur.taille; i++)
 1705:         {
 1706:             ((real8 **) (*((struct_matrice *) (*s_objet_resultat_2).objet))
 1707:                     .tableau)[i][i] = ((real8 *) (s_vecteur.tableau))[i];
 1708:         }
 1709: 
 1710:         free(s_vecteur.tableau);
 1711: 
 1712:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1713:                 s_objet_resultat_3) == d_erreur)
 1714:         {
 1715:             return;
 1716:         }
 1717: 
 1718:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1719:                 s_objet_resultat_2) == d_erreur)
 1720:         {
 1721:             return;
 1722:         }
 1723: 
 1724:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1725:                 s_objet_resultat_1) == d_erreur)
 1726:         {
 1727:             return;
 1728:         }
 1729:     }
 1730:     else if ((*s_objet_argument).type == MCX)
 1731:     {
 1732:         if ((s_objet_resultat_1 = allocation(s_etat_processus, MCX)) == NULL)
 1733:         {
 1734:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1735:             return;
 1736:         }
 1737: 
 1738:         if ((s_objet_resultat_2 = allocation(s_etat_processus, MRL)) == NULL)
 1739:         {
 1740:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1741:             return;
 1742:         }
 1743: 
 1744:         if ((s_objet_resultat_3 = allocation(s_etat_processus, MCX)) == NULL)
 1745:         {
 1746:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1747:             return;
 1748:         }
 1749: 
 1750:         valeurs_singulieres(s_etat_processus, (*s_objet_argument).objet,
 1751:                 (*s_objet_resultat_3).objet, &s_vecteur,
 1752:                 (*s_objet_resultat_1).objet);
 1753: 
 1754:         if ((*s_etat_processus).erreur_systeme != d_es)
 1755:         {
 1756:             return;
 1757:         }
 1758: 
 1759:         if (((*s_etat_processus).erreur_execution != d_ex) ||
 1760:                 ((*s_etat_processus).exception != d_ep))
 1761:         {
 1762:             liberation(s_etat_processus, s_objet_resultat_1);
 1763:             liberation(s_etat_processus, s_objet_resultat_2);
 1764:             liberation(s_etat_processus, s_objet_resultat_3);
 1765:             liberation(s_etat_processus, s_objet_argument);
 1766:             return;
 1767:         }
 1768: 
 1769:         (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_colonnes =
 1770:                 (*((struct_matrice *) (*s_objet_argument).objet))
 1771:                 .nombre_colonnes;
 1772:         (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_lignes =
 1773:                 (*((struct_matrice *) (*s_objet_argument).objet))
 1774:                 .nombre_lignes;
 1775: 
 1776:         if (((*((struct_matrice *) (*s_objet_resultat_2).objet)).tableau =
 1777:                 malloc((*((struct_matrice *) (*s_objet_resultat_2).objet))
 1778:                 .nombre_lignes * sizeof(real8 *))) == NULL)
 1779:         {
 1780:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1781:             return;
 1782:         }
 1783: 
 1784:         for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat_2).objet))
 1785:                 .nombre_lignes; i++)
 1786:         {
 1787:             if ((((real8 **) (*((struct_matrice *) (*s_objet_resultat_2)
 1788:                     .objet)).tableau)[i] = malloc((*((struct_matrice *)
 1789:                     (*s_objet_resultat_2).objet)).nombre_colonnes *
 1790:                     sizeof(real8 *))) == NULL)
 1791:             {
 1792:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1793:                 return;
 1794:             }
 1795: 
 1796:             for(j = 0; j < (*((struct_matrice *) (*s_objet_resultat_2).objet))
 1797:                     .nombre_colonnes; j++)
 1798:             {
 1799:                 ((real8 **) (*((struct_matrice *) (*s_objet_resultat_2)
 1800:                         .objet)).tableau)[i][j] = 0;
 1801:             }
 1802:         }
 1803: 
 1804:         for(i = 0; i < s_vecteur.taille; i++)
 1805:         {
 1806:             ((real8 **) (*((struct_matrice *) (*s_objet_resultat_2).objet))
 1807:                     .tableau)[i][i] = ((real8 *) (s_vecteur.tableau))[i];
 1808:         }
 1809: 
 1810:         free(s_vecteur.tableau);
 1811: 
 1812:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1813:                 s_objet_resultat_3) == d_erreur)
 1814:         {
 1815:             return;
 1816:         }
 1817: 
 1818:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1819:                 s_objet_resultat_2) == d_erreur)
 1820:         {
 1821:             return;
 1822:         }
 1823: 
 1824:         if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1825:                 s_objet_resultat_1) == d_erreur)
 1826:         {
 1827:             return;
 1828:         }
 1829:     }
 1830:     else
 1831:     {
 1832:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1833: 
 1834:         liberation(s_etat_processus, s_objet_argument);
 1835:         return;
 1836:     }
 1837: 
 1838:     liberation(s_etat_processus, s_objet_argument);
 1839:     return;
 1840: }
 1841: 
 1842: 
 1843: /*
 1844: ================================================================================
 1845:   Fonction 'swapcntxt'
 1846: ================================================================================
 1847:   Entrées :
 1848: --------------------------------------------------------------------------------
 1849:   Sorties :
 1850: --------------------------------------------------------------------------------
 1851:   Effets de bord : néant
 1852: ================================================================================
 1853: */
 1854: 
 1855: void
 1856: instruction_swapcntxt(struct_processus *s_etat_processus)
 1857: {
 1858:     integer8                    i;
 1859:     integer8                    registre_taille;
 1860: 
 1861:     struct_liste_chainee        *l_element_courant;
 1862:     struct_liste_chainee        *l_element_courant_taille;
 1863:     struct_liste_chainee        *registre;
 1864: 
 1865:     struct_objet                *s_objet_argument;
 1866: 
 1867:     (*s_etat_processus).erreur_execution = d_ex;
 1868: 
 1869:     if ((*s_etat_processus).affichage_arguments == 'Y')
 1870:     {
 1871:         printf("\n  SWAPCNTXT ");
 1872: 
 1873:         if ((*s_etat_processus).langue == 'F')
 1874:         {
 1875:             printf("(échange de contextes)\n\n");
 1876:         }
 1877:         else
 1878:         {
 1879:             printf("(swap contexts)\n\n");
 1880:         }
 1881: 
 1882:         printf("    1: %s\n", d_INT);
 1883:         return;
 1884:     }
 1885:     else if ((*s_etat_processus).test_instruction == 'Y')
 1886:     {
 1887:         (*s_etat_processus).nombre_arguments = -1;
 1888:         return;
 1889:     }
 1890:     
 1891:     if (test_cfsf(s_etat_processus, 31) == d_vrai)
 1892:     {
 1893:         if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
 1894:         {
 1895:             return;
 1896:         }
 1897:     }
 1898: 
 1899:     if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
 1900:             &s_objet_argument) == d_erreur)
 1901:     {
 1902:         (*s_etat_processus).erreur_execution = d_ex_manque_argument;
 1903:         return;
 1904:     }
 1905: 
 1906:     if ((*s_objet_argument).type == INT)
 1907:     {
 1908:         l_element_courant = (*s_etat_processus).l_base_pile_contextes;
 1909:         l_element_courant_taille = (*s_etat_processus)
 1910:                 .l_base_pile_taille_contextes;
 1911: 
 1912:         i = (*((integer8 *) (*s_objet_argument).objet));
 1913: 
 1914:         while((l_element_courant != NULL) && (l_element_courant_taille != NULL))
 1915:         {
 1916:             i--;
 1917: 
 1918:             if (i == 0)
 1919:             {
 1920:                 break;
 1921:             }
 1922: 
 1923:             l_element_courant = (*l_element_courant).suivant;
 1924:             l_element_courant_taille = (*l_element_courant_taille).suivant;
 1925:         }
 1926: 
 1927:         if ((l_element_courant == NULL) || (l_element_courant_taille == NULL))
 1928:         {
 1929:             liberation(s_etat_processus, s_objet_argument);
 1930: 
 1931:             (*s_etat_processus).erreur_execution = d_ex_contexte;
 1932:             return;
 1933:         }
 1934: 
 1935:         if ((*(*l_element_courant).donnee).type != LST)
 1936:         {
 1937:             (*s_etat_processus).erreur_systeme = d_es_contexte;
 1938:             return;
 1939:         }
 1940: 
 1941:         if ((*(*l_element_courant_taille).donnee).type != INT)
 1942:         {
 1943:             (*s_etat_processus).erreur_systeme = d_es_contexte;
 1944:             return;
 1945:         }
 1946: 
 1947:         registre = (*s_etat_processus).l_base_pile;
 1948:         registre_taille = (*s_etat_processus).hauteur_pile_operationnelle;
 1949: 
 1950:         (*s_etat_processus).l_base_pile = (*(*l_element_courant).donnee).objet;
 1951:         (*s_etat_processus).hauteur_pile_operationnelle =
 1952:                 (*((integer8 *) (*(*l_element_courant_taille).donnee).objet));
 1953: 
 1954:         (*(*l_element_courant).donnee).objet = registre;
 1955:         (*((integer8 *) (*(*l_element_courant_taille).donnee).objet)) =
 1956:                 registre_taille;
 1957:     }
 1958:     else
 1959:     {
 1960:         liberation(s_etat_processus, s_objet_argument);
 1961: 
 1962:         (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
 1963:         return;
 1964:     }
 1965: 
 1966:     liberation(s_etat_processus, s_objet_argument);
 1967: }
 1968: 
 1969: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>