Annotation of rpl/src/gestion_variables_partagees.c, revision 1.1

1.1     ! bertrand    1: /*
        !             2: ================================================================================
        !             3:   RPL/2 (R) version 4.0.9
        !             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>