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

1.1       bertrand    1: /*
                      2: ================================================================================
1.36      bertrand    3:   RPL/2 (R) version 4.1.11
1.30      bertrand    4:   Copyright (C) 1989-2012 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: 
1.38    ! bertrand   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: 
1.37      bertrand   77: #if 0
1.1       bertrand   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: }
1.37      bertrand  508: #endif
1.1       bertrand  509: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>