/* ================================================================================ RPL/2 (R) version 4.1.0.prerelease.0 Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Routine de création d'une nouvelle variable partagee ================================================================================ Entrée : -------------------------------------------------------------------------------- Sortie : -------------------------------------------------------------------------------- Effets de bords : néant ================================================================================ */ logical1 creation_variable_partagee(struct_processus *s_etat_processus, struct_variable_partagee *s_variable) { struct_variable_partagee *s_nouvelle_base; long i; (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables++; if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables > (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees) { // La nouvelle variable partagée ne tient pas dans la table existante. // Il convient donc d'en augmenter la taille. if ((*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees == 0) { (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees = (*(*s_etat_processus) .s_liste_variables_partagees).nombre_variables; } else { while((*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables > (*(*s_etat_processus) .s_liste_variables_partagees).nombre_variables_allouees) { (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees *= 2; } } if ((s_nouvelle_base = realloc((struct_variable_partagee *) (*(*s_etat_processus).s_liste_variables_partagees).table, (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees * sizeof(struct_variable_partagee))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables--; return(d_erreur); } (*(*s_etat_processus).s_liste_variables_partagees).table = s_nouvelle_base; } /* * Positionnement de la variable partagée au bon endroit */ if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables == 1) { (*(*s_etat_processus).s_liste_variables_partagees).table[0] = (*s_variable); } else { for(i = (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables - 2; i >= 0; i--) { if (strcmp((*s_variable).nom, (*(*s_etat_processus) .s_liste_variables_partagees).table[i].nom) < 0) { (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1] = (*(*s_etat_processus).s_liste_variables_partagees) .table[i]; } else { break; } } (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1] = (*s_variable); } return d_absence_erreur; } /* ================================================================================ Procédure de retrait d'une variable partagee de la base ================================================================================ Entrée : -------------------------------------------------------------------------------- Sortie : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 retrait_variable_partagee(struct_processus *s_etat_processus, unsigned char *nom_variable, union_position_variable position) { struct_variable_partagee *s_nouvelle_base; logical1 erreur; unsigned long position_courante; unsigned long position_supprimee; if (recherche_variable_partagee(s_etat_processus, nom_variable, position, ((*s_etat_processus).mode_execution_programme == 'Y') ? 'P' : 'E') == d_vrai) { if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables < ((*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees / 2)) { (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees /= 2; if ((s_nouvelle_base = realloc((struct_variable_partagee *) (*(*s_etat_processus).s_liste_variables_partagees).table, (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables_allouees * sizeof(struct_variable_partagee))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } (*(*s_etat_processus).s_liste_variables_partagees).table = s_nouvelle_base; } position_supprimee = (*(*s_etat_processus) .s_liste_variables_partagees).position_variable; liberation(s_etat_processus, (*(*s_etat_processus) .s_liste_variables_partagees).table[position_supprimee].objet); free((*(*s_etat_processus).s_liste_variables_partagees) .table[position_supprimee].nom); (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables--; for(position_courante = position_supprimee; position_courante < (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables; position_courante++) { (*(*s_etat_processus).s_liste_variables_partagees).table [position_courante] = (*(*s_etat_processus) .s_liste_variables_partagees).table[position_courante + 1]; } erreur = d_absence_erreur; } else { erreur = d_erreur; (*s_etat_processus).erreur_systeme = d_es_variable_introuvable; } return erreur; } /* ================================================================================ Procédure de recherche d'une variable partagee par son nom dans la base ================================================================================ Entrée : -------------------------------------------------------------------------------- Sortie : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 recherche_variable_partagee(struct_processus *s_etat_processus, unsigned char *nom_variable, union_position_variable position, unsigned char origine) { logical1 existence_variable; long difference; long difference_inferieure; long difference_superieure; unsigned long borne_inferieure; unsigned long borne_superieure; unsigned long moyenne; unsigned long nombre_iterations_maximal; unsigned long ordre_iteration; if ((*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables == 0) { (*s_etat_processus).erreur_systeme = d_es_variable_introuvable; return d_faux; } ordre_iteration = 0; nombre_iterations_maximal = ((unsigned long) (log((*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables) / log(2))) + 2; borne_inferieure = 0; borne_superieure = (*(*s_etat_processus).s_liste_variables_partagees) .nombre_variables - 1; do { moyenne = (borne_inferieure + borne_superieure) / 2; ordre_iteration++; if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2))) == (borne_inferieure + borne_superieure)) { difference = strcmp(nom_variable, (*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].nom); if (difference != 0) { if (difference > 0) { borne_inferieure = moyenne; } else { borne_superieure = moyenne; } } } else { difference_inferieure = strcmp(nom_variable, (*(*s_etat_processus).s_liste_variables_partagees).table [moyenne].nom); difference_superieure = strcmp(nom_variable, (*(*s_etat_processus).s_liste_variables_partagees).table [moyenne + 1].nom); if (difference_inferieure == 0) { difference = 0; } else if (difference_superieure == 0) { difference = 0; moyenne++; } else { difference = difference_inferieure; if (difference > 0) { borne_inferieure = moyenne; } else { borne_superieure = moyenne; } } } } while((difference != 0) && (ordre_iteration <= nombre_iterations_maximal)); if (ordre_iteration > nombre_iterations_maximal) { existence_variable = d_faux; (*s_etat_processus).erreur_systeme = d_es_variable_introuvable; } else { // Reste à rechercher la variable déclarée à la position 'position'... if ((*(*s_etat_processus).s_liste_variables_partagees).table[moyenne] .origine == 'P') { if (((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].variable_partagee.adresse == position.adresse) && ((*(*s_etat_processus) .s_liste_variables_partagees).table[moyenne] .origine == origine)) { existence_variable = d_vrai; } else { existence_variable = d_faux; } } else { if (((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].variable_partagee.pointeur == position.pointeur) && ((*(*s_etat_processus) .s_liste_variables_partagees).table[moyenne] .origine == origine)) { existence_variable = d_vrai; } else { existence_variable = d_faux; } } if (existence_variable == d_faux) { // On rembobine. if (moyenne > 0) { while(strcmp(nom_variable, (*(*s_etat_processus) .s_liste_variables_partagees).table[moyenne - 1].nom) == 0) { moyenne--; if (moyenne == 0) { break; } } } // Un petit test pour voir si le premier élément du tableau // peut correspondre au critère de recherche. existence_variable = d_faux; if (strcmp((*(*s_etat_processus).s_liste_variables_partagees).table [moyenne].nom, nom_variable) == 0) { if ((*(*s_etat_processus).s_liste_variables_partagees).table [moyenne].origine == 'P') { if (((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].variable_partagee.adresse == position.adresse) && ((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].origine == origine)) { existence_variable = d_vrai; } } else { if (((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].variable_partagee.pointeur == position.pointeur) && ((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].origine == origine)) { existence_variable = d_vrai; } } } // Puis on balaye dans le sens croissant. if (((moyenne + 1) < (*(*s_etat_processus) .s_liste_variables_partagees).nombre_variables) && (existence_variable == d_faux)) { while(strcmp((*(*s_etat_processus) .s_liste_variables_partagees).table[moyenne + 1].nom, nom_variable) == 0) { moyenne++; if ((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].origine == 'P') { if (((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].variable_partagee.adresse == position.adresse) && ((*(*s_etat_processus) .s_liste_variables_partagees) .table[moyenne].origine == origine)) { existence_variable = d_vrai; break; } } else { if (((*(*s_etat_processus).s_liste_variables_partagees) .table[moyenne].variable_partagee.pointeur == position.pointeur) && ((*(*s_etat_processus) .s_liste_variables_partagees) .table[moyenne].origine == origine)) { existence_variable = d_vrai; break; } } if ((moyenne + 1) >= (*(*s_etat_processus) .s_liste_variables_partagees).nombre_variables) { break; } } } } (*(*s_etat_processus).s_liste_variables_partagees).position_variable = moyenne; } /* * Si la variable partagée n'existe pas, elle a été rendue privée par un * thread concurrent. Il faut donc l'enlever de la table des variables * du thread courant. */ if (existence_variable == d_faux) { if (retrait_variable(s_etat_processus, nom_variable, 'L') == d_faux) { return d_faux; } } return existence_variable; } // vim: ts=4