File:  [local] / rpl / src / instructions_s10.c
Revision 1.45: download - view: text, annotated - select for diffs - revision graph
Thu Sep 15 17:51:43 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Suite des patches. Attention, il reste une 'race condition' quelque part...

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

CVSweb interface <joel.bertrand@systella.fr>