File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Wed Jan 27 22:22:11 2010 UTC (14 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_0_10, HEAD


Changement de version pour la 4.0.10.
Correction d'un dysfonctionnement dans le retour des erreurs des fonctions
RPL/C lorsque le programme est compilé (routine evaluation()).

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.10
    4:   Copyright (C) 1989-2010 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #include "rpl.conv.h"
   24: 
   25: 
   26: /*
   27: ================================================================================
   28:   Routine de création d'une nouvelle variable partagee
   29: ================================================================================
   30:   Entrée :
   31: --------------------------------------------------------------------------------
   32:   Sortie :
   33: --------------------------------------------------------------------------------
   34:   Effets de bords : néant
   35: ================================================================================
   36: */
   37: 
   38: logical1
   39: creation_variable_partagee(struct_processus *s_etat_processus,
   40:         struct_variable_partagee *s_variable)
   41: {
   42:     struct_variable_partagee            *s_nouvelle_base;
   43: 
   44:     long                                i;
   45: 
   46:     (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables++;
   47: 
   48:     if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables >
   49:             (*(*s_etat_processus).s_liste_variables_partagees)
   50:             .nombre_variables_allouees)
   51:     {
   52:         // La nouvelle variable partagée ne tient pas dans la table existante.
   53:         // Il convient donc d'en augmenter la taille.
   54: 
   55:         if ((*(*s_etat_processus).s_liste_variables_partagees)
   56:                 .nombre_variables_allouees == 0)
   57:         {
   58:             (*(*s_etat_processus).s_liste_variables_partagees)
   59:                     .nombre_variables_allouees = (*(*s_etat_processus)
   60:                     .s_liste_variables_partagees).nombre_variables;
   61:         }
   62:         else
   63:         {
   64:             while((*(*s_etat_processus).s_liste_variables_partagees)
   65:                     .nombre_variables > (*(*s_etat_processus)
   66:                     .s_liste_variables_partagees).nombre_variables_allouees)
   67:             {
   68:                 (*(*s_etat_processus).s_liste_variables_partagees)
   69:                         .nombre_variables_allouees *= 2;
   70:             }
   71:         }
   72: 
   73:         if ((s_nouvelle_base = realloc((struct_variable_partagee *)
   74:                 (*(*s_etat_processus).s_liste_variables_partagees).table,
   75:                 (*(*s_etat_processus).s_liste_variables_partagees)
   76:                 .nombre_variables_allouees *
   77:                 sizeof(struct_variable_partagee))) == NULL)
   78:         {
   79:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   80:             (*(*s_etat_processus).s_liste_variables_partagees)
   81:                     .nombre_variables--;
   82:             return(d_erreur);
   83:         }
   84: 
   85:         (*(*s_etat_processus).s_liste_variables_partagees).table =
   86:                 s_nouvelle_base;
   87:     }
   88: 
   89:     /*
   90:      * Positionnement de la variable partagée au bon endroit
   91:      */
   92: 
   93:     if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables
   94:             == 1)
   95:     {
   96:         (*(*s_etat_processus).s_liste_variables_partagees).table[0]
   97:                 = (*s_variable);
   98:     }
   99:     else
  100:     {
  101:         for(i = (*(*s_etat_processus).s_liste_variables_partagees)
  102:                 .nombre_variables - 2; i >= 0; i--)
  103:         {
  104:             if (strcmp((*s_variable).nom, (*(*s_etat_processus)
  105:                     .s_liste_variables_partagees).table[i].nom) < 0)
  106:             {
  107:                 (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1]
  108:                         = (*(*s_etat_processus).s_liste_variables_partagees)
  109:                         .table[i];
  110:             }
  111:             else
  112:             {
  113:                 break;
  114:             }
  115:         }
  116: 
  117:         (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1]
  118:                 = (*s_variable);
  119:     }
  120: 
  121:     return d_absence_erreur;
  122: }
  123: 
  124: 
  125: /*
  126: ================================================================================
  127:   Procédure de retrait d'une variable partagee de la base
  128: ================================================================================
  129:   Entrée :
  130: --------------------------------------------------------------------------------
  131:   Sortie :
  132: --------------------------------------------------------------------------------
  133:   Effets de bord : néant
  134: ================================================================================
  135: */
  136: 
  137: logical1
  138: retrait_variable_partagee(struct_processus *s_etat_processus,
  139:         unsigned char *nom_variable, union_position_variable position)
  140: {
  141:     struct_variable_partagee        *s_nouvelle_base;
  142: 
  143:     logical1                        erreur;
  144: 
  145:     unsigned long                   position_courante;
  146:     unsigned long                   position_supprimee;
  147: 
  148:     if (recherche_variable_partagee(s_etat_processus, nom_variable,
  149:             position, ((*s_etat_processus).mode_execution_programme == 'Y')
  150:             ? 'P' : 'E') == d_vrai)
  151:     {
  152:         if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables
  153:                 < ((*(*s_etat_processus).s_liste_variables_partagees)
  154:                 .nombre_variables_allouees / 2))
  155:         {
  156:             (*(*s_etat_processus).s_liste_variables_partagees)
  157:                     .nombre_variables_allouees /= 2;
  158: 
  159:             if ((s_nouvelle_base = realloc((struct_variable_partagee *)
  160:                     (*(*s_etat_processus).s_liste_variables_partagees).table,
  161:                     (*(*s_etat_processus).s_liste_variables_partagees)
  162:                     .nombre_variables_allouees *
  163:                     sizeof(struct_variable_partagee))) == NULL)
  164:             {
  165:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  166:                 return(d_erreur);
  167:             }
  168: 
  169:             (*(*s_etat_processus).s_liste_variables_partagees).table =
  170:                     s_nouvelle_base;
  171:         }
  172: 
  173:         position_supprimee = (*(*s_etat_processus)
  174:                 .s_liste_variables_partagees).position_variable;
  175: 
  176:         liberation(s_etat_processus, (*(*s_etat_processus)
  177:                 .s_liste_variables_partagees).table[position_supprimee].objet);
  178:         free((*(*s_etat_processus).s_liste_variables_partagees)
  179:                 .table[position_supprimee].nom);
  180: 
  181:         (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables--;
  182: 
  183:         for(position_courante = position_supprimee; position_courante <
  184:                 (*(*s_etat_processus).s_liste_variables_partagees)
  185:                 .nombre_variables; position_courante++)
  186:         {
  187:             (*(*s_etat_processus).s_liste_variables_partagees).table
  188:                     [position_courante] = (*(*s_etat_processus)
  189:                     .s_liste_variables_partagees).table[position_courante + 1];
  190:         }
  191: 
  192:         erreur = d_absence_erreur;
  193:     }
  194:     else
  195:     {
  196:         erreur = d_erreur;
  197:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  198:     }
  199: 
  200:     return erreur;
  201: }
  202: 
  203: 
  204: /*
  205: ================================================================================
  206:   Procédure de recherche d'une variable partagee par son nom dans la base
  207: ================================================================================
  208:   Entrée :
  209: --------------------------------------------------------------------------------
  210:   Sortie :
  211: --------------------------------------------------------------------------------
  212:   Effets de bord : néant
  213: ================================================================================
  214: */
  215: 
  216: logical1
  217: recherche_variable_partagee(struct_processus *s_etat_processus,
  218:         unsigned char *nom_variable, union_position_variable position,
  219:         unsigned char origine)
  220: {
  221:     logical1                    existence_variable;
  222: 
  223:     long                        difference;
  224:     long                        difference_inferieure;
  225:     long                        difference_superieure;
  226: 
  227:     unsigned long               borne_inferieure;
  228:     unsigned long               borne_superieure;
  229:     unsigned long               moyenne;
  230:     unsigned long               nombre_iterations_maximal;
  231:     unsigned long               ordre_iteration;
  232: 
  233:     if ((*(*s_etat_processus).s_liste_variables_partagees)
  234:             .nombre_variables == 0)
  235:     {
  236:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  237:         return d_faux;
  238:     }
  239: 
  240:     ordre_iteration = 0;
  241:     nombre_iterations_maximal = ((unsigned long)
  242:             (log((*(*s_etat_processus).s_liste_variables_partagees)
  243:             .nombre_variables) / log(2))) + 2;
  244: 
  245:     borne_inferieure = 0;
  246:     borne_superieure = (*(*s_etat_processus).s_liste_variables_partagees)
  247:             .nombre_variables - 1;
  248: 
  249:     do
  250:     {
  251:         moyenne = (borne_inferieure + borne_superieure) / 2;
  252:         ordre_iteration++;
  253: 
  254:         if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2)))
  255:                 == (borne_inferieure + borne_superieure))
  256:         {
  257:             difference = strcmp(nom_variable,
  258:                     (*(*s_etat_processus).s_liste_variables_partagees)
  259:                     .table[moyenne].nom);
  260: 
  261:             if (difference != 0)
  262:             {
  263:                 if (difference > 0)
  264:                 {
  265:                     borne_inferieure = moyenne;
  266:                 }
  267:                 else
  268:                 {
  269:                     borne_superieure = moyenne;
  270:                 }
  271:             }
  272:         }
  273:         else
  274:         {
  275:             difference_inferieure = strcmp(nom_variable,
  276:                     (*(*s_etat_processus).s_liste_variables_partagees).table
  277:                     [moyenne].nom);
  278:             difference_superieure = strcmp(nom_variable,
  279:                     (*(*s_etat_processus).s_liste_variables_partagees).table
  280:                     [moyenne + 1].nom);
  281: 
  282:             if (difference_inferieure == 0)
  283:             {
  284:                 difference = 0;
  285:             }
  286:             else if (difference_superieure == 0)
  287:             {
  288:                 difference = 0;
  289:                 moyenne++;
  290:             }
  291:             else
  292:             {
  293:                 difference = difference_inferieure;
  294: 
  295:                 if (difference > 0)
  296:                 {
  297:                     borne_inferieure = moyenne;
  298:                 }
  299:                 else
  300:                 {
  301:                     borne_superieure = moyenne;
  302:                 }
  303:             }
  304:         }
  305:     } while((difference != 0) &&
  306:             (ordre_iteration <= nombre_iterations_maximal));
  307: 
  308:     if (ordre_iteration > nombre_iterations_maximal)
  309:     {
  310:         existence_variable = d_faux;
  311:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  312:     }
  313:     else
  314:     {
  315:         // Reste à rechercher la variable déclarée à la position 'position'...
  316: 
  317:         if ((*(*s_etat_processus).s_liste_variables_partagees).table[moyenne]
  318:                 .origine == 'P')
  319:         {
  320:             if (((*(*s_etat_processus).s_liste_variables_partagees)
  321:                     .table[moyenne].variable_partagee.adresse ==
  322:                     position.adresse) && ((*(*s_etat_processus)
  323:                     .s_liste_variables_partagees).table[moyenne]
  324:                     .origine == origine))
  325:             {
  326:                 existence_variable = d_vrai;
  327:             }
  328:             else
  329:             {
  330:                 existence_variable = d_faux;
  331:             }
  332:         }
  333:         else
  334:         {
  335:             if (((*(*s_etat_processus).s_liste_variables_partagees)
  336:                     .table[moyenne].variable_partagee.pointeur ==
  337:                     position.pointeur) && ((*(*s_etat_processus)
  338:                     .s_liste_variables_partagees).table[moyenne]
  339:                     .origine == origine))
  340:             {
  341:                 existence_variable = d_vrai;
  342:             }
  343:             else
  344:             {
  345:                 existence_variable = d_faux;
  346:             }
  347:         }
  348: 
  349:         if (existence_variable == d_faux)
  350:         {
  351:             // On rembobine.
  352: 
  353:             if (moyenne > 0)
  354:             {
  355:                 while(strcmp(nom_variable, (*(*s_etat_processus)
  356:                         .s_liste_variables_partagees).table[moyenne - 1].nom)
  357:                         == 0)
  358:                 {
  359:                     moyenne--;
  360: 
  361:                     if (moyenne == 0)
  362:                     {
  363:                         break;
  364:                     }
  365:                 }
  366:             }
  367: 
  368:             // Un petit test pour voir si le premier élément du tableau
  369:             // peut correspondre au critère de recherche.
  370: 
  371:             existence_variable = d_faux;
  372: 
  373:             if (strcmp((*(*s_etat_processus).s_liste_variables_partagees).table
  374:                     [moyenne].nom, nom_variable) == 0)
  375:             {
  376:                 if ((*(*s_etat_processus).s_liste_variables_partagees).table
  377:                         [moyenne].origine == 'P')
  378:                 {
  379:                     if (((*(*s_etat_processus).s_liste_variables_partagees)
  380:                             .table[moyenne].variable_partagee.adresse
  381:                             == position.adresse) &&
  382:                             ((*(*s_etat_processus).s_liste_variables_partagees)
  383:                             .table[moyenne].origine == origine))
  384:                     {
  385:                         existence_variable = d_vrai;
  386:                     }
  387:                 }
  388:                 else
  389:                 {
  390:                     if (((*(*s_etat_processus).s_liste_variables_partagees)
  391:                             .table[moyenne].variable_partagee.pointeur
  392:                             == position.pointeur) &&
  393:                             ((*(*s_etat_processus).s_liste_variables_partagees)
  394:                             .table[moyenne].origine == origine))
  395:                     {
  396:                         existence_variable = d_vrai;
  397:                     }
  398:                 }
  399:             }
  400: 
  401:             // Puis on balaye dans le sens croissant.
  402: 
  403:             if (((moyenne + 1) < (*(*s_etat_processus)
  404:                     .s_liste_variables_partagees).nombre_variables)
  405:                     && (existence_variable == d_faux))
  406:             {
  407:                 while(strcmp((*(*s_etat_processus)
  408:                         .s_liste_variables_partagees).table[moyenne + 1].nom,
  409:                         nom_variable) == 0)
  410:                 {
  411:                     moyenne++;
  412: 
  413:                     if ((*(*s_etat_processus).s_liste_variables_partagees)
  414:                             .table[moyenne].origine == 'P')
  415:                     {
  416:                         if (((*(*s_etat_processus).s_liste_variables_partagees)
  417:                                 .table[moyenne].variable_partagee.adresse ==
  418:                                 position.adresse) && ((*(*s_etat_processus)
  419:                                 .s_liste_variables_partagees)
  420:                                 .table[moyenne].origine == origine))
  421:                         {
  422:                             existence_variable = d_vrai;
  423:                             break;
  424:                         }
  425:                     }
  426:                     else
  427:                     {
  428:                         if (((*(*s_etat_processus).s_liste_variables_partagees)
  429:                                 .table[moyenne].variable_partagee.pointeur ==
  430:                                 position.pointeur) && ((*(*s_etat_processus)
  431:                                 .s_liste_variables_partagees)
  432:                                 .table[moyenne].origine == origine))
  433:                         {
  434:                             existence_variable = d_vrai;
  435:                             break;
  436:                         }
  437:                     }
  438: 
  439:                     if ((moyenne + 1) >= (*(*s_etat_processus)
  440:                             .s_liste_variables_partagees).nombre_variables)
  441:                     {
  442:                         break;
  443:                     }
  444:                 }
  445:             }
  446:         }
  447: 
  448:         (*(*s_etat_processus).s_liste_variables_partagees).position_variable
  449:                 = moyenne;
  450:     }
  451: 
  452:     /*
  453:      * Si la variable partagée n'existe pas, elle a été rendue privée par un
  454:      * thread concurrent. Il faut donc l'enlever de la table des variables
  455:      * du thread courant.
  456:      */
  457: 
  458:     if (existence_variable == d_faux)
  459:     {
  460:         if (retrait_variable(s_etat_processus, nom_variable, 'L') == d_faux)
  461:         {
  462:             return d_faux;
  463:         }
  464:     }
  465: 
  466:     return existence_variable;
  467: }
  468: 
  469: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>