File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.38: download - view: text, annotated - select for diffs - revision graph
Fri Dec 14 14:19:49 2012 UTC (11 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction de la gestion des variables partagées pour que le RPL/2 puisse
être compilé sans erreur. Attention, la sortie du logiciel échoue sur un
SIGBUS car la fonction de libération des variables partagées n'est pas encore
écrite.

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

CVSweb interface <joel.bertrand@systella.fr>