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

1.1       bertrand    1: /*
                      2: ================================================================================
1.25    ! bertrand    3:   RPL/2 (R) version 4.1.1
1.15      bertrand    4:   Copyright (C) 1989-2011 Dr. BERTRAND Joël
1.1       bertrand    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: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   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>