File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.37: download - view: text, annotated - select for diffs - revision graph
Thu Dec 13 16:59:41 2012 UTC (11 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Première série de patches pour inclure les variables partagées dans
l'arbre des variables. Attention, le résultat ne compile pas.

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

CVSweb interface <joel.bertrand@systella.fr>