Diff for /rpl/src/gestion_variables_partagees.c between versions 1.8 and 1.72

version 1.8, 2010/05/24 10:58:30 version 1.72, 2020/01/10 11:15:43
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.0.16    RPL/2 (R) version 4.1.32
   Copyright (C) 1989-2010 Dr. BERTRAND Joël    Copyright (C) 1989-2020 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 20 Line 20
 */  */
   
   
 #include "rpl.conv.h"  #include "rpl-conv.h"
   
   
   /*
   ================================================================================
     Routine de gestion du cache des objets
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : néant
   ================================================================================
   */
   
   static inline struct_arbre_variables_partagees *
   allocation_noeud_partage(struct_processus *s_etat_processus)
   {
       struct_arbre_variables_partagees            *objet;
   
       if ((*s_etat_processus).pointeur_variables_partagees_noeud > 0)
       {
           objet = (*s_etat_processus).variables_partagees_noeud
                   [--(*s_etat_processus).pointeur_variables_partagees_noeud];
       }
       else
       {
           objet = malloc(sizeof(struct_arbre_variables_partagees));
       }
   
       return(objet);
   }
   
   static inline void
   liberation_noeud_partage(struct_processus *s_etat_processus,
           struct_arbre_variables_partagees *objet)
   {
       if ((*s_etat_processus).pointeur_variables_partagees_noeud < TAILLE_CACHE)
       {
           (*s_etat_processus).variables_partagees_noeud
                   [(*s_etat_processus).pointeur_variables_partagees_noeud++] =
                   objet;
       }
       else
       {
           free(objet);
       }
   
       return;
   }
   
   static inline struct_arbre_variables_partagees **
   allocation_tableau_noeuds_partages(struct_processus *s_etat_processus)
   {
       struct_arbre_variables_partagees            **objet;
   
       if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages > 0)
       {
           objet = (*s_etat_processus).variables_tableau_noeuds_partages
                   [--(*s_etat_processus)
                   .pointeur_variables_tableau_noeuds_partages];
       }
       else
       {
           objet = malloc(((size_t) (*s_etat_processus)
                   .nombre_caracteres_variables)
                   * sizeof(struct_arbre_variables_partagees *));
       }
   
       return(objet);
   }
   
   static inline void
   liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
           struct_arbre_variables_partagees **objet)
   {
       if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages
               < TAILLE_CACHE)
       {
           (*s_etat_processus).variables_tableau_noeuds_partages
                   [(*s_etat_processus)
                   .pointeur_variables_tableau_noeuds_partages++] = objet;
       }
       else
       {
           free(objet);
       }
   
       return;
   }
   
   
 /*  /*
Line 39  logical1 Line 128  logical1
 creation_variable_partagee(struct_processus *s_etat_processus,  creation_variable_partagee(struct_processus *s_etat_processus,
         struct_variable_partagee *s_variable)          struct_variable_partagee *s_variable)
 {  {
     struct_variable_partagee            *s_nouvelle_base;      int                                     i;
   
     long                                i;      struct_arbre_variables_partagees        *l_variable_courante;
   
     (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables++;      struct_liste_variables_partagees        *l_nouvel_element;
   
     if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables >      unsigned char                           *ptr;
             (*(*s_etat_processus).s_liste_variables_partagees)  
             .nombre_variables_allouees)      // Ajout de la variable en tête de la liste des variables partagées
   
       if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
               == NULL)
     {      {
         // La nouvelle variable partagée ne tient pas dans la table existante.          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
         // Il convient donc d'en augmenter la taille.          return(d_erreur);
       }
   
         if ((*(*s_etat_processus).s_liste_variables_partagees)      if (((*l_nouvel_element).variable = malloc(sizeof(
                 .nombre_variables_allouees == 0)              struct_variable_partagee))) == NULL)
         {      {
             (*(*s_etat_processus).s_liste_variables_partagees)          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                     .nombre_variables_allouees = (*(*s_etat_processus)          return(d_erreur);
                     .s_liste_variables_partagees).nombre_variables;      }
         }  
         else      (*(*l_nouvel_element).variable) = (*s_variable);
       (*l_nouvel_element).pid = getpid();
       (*l_nouvel_element).tid = pthread_self();
   
       if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
       }
   
       (*l_nouvel_element).suivant = (*(*s_etat_processus)
               .l_liste_variables_partagees);
       (*l_nouvel_element).precedent = NULL;
   
       if ((*(*s_etat_processus).l_liste_variables_partagees) != NULL)
       {
           (**(*s_etat_processus).l_liste_variables_partagees).precedent
                   = l_nouvel_element;
       }
   
       (*(*s_etat_processus).l_liste_variables_partagees) = l_nouvel_element;
   
       // Ajout de la variable à la feuille de l'arbre des variables partagees
   
       if ((*(*s_etat_processus).s_arbre_variables_partagees) == NULL)
       {
           if (((*(*s_etat_processus).s_arbre_variables_partagees) =
                       allocation_noeud_partage(s_etat_processus)) == NULL)
         {          {
             while((*(*s_etat_processus).s_liste_variables_partagees)              if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
                     .nombre_variables > (*(*s_etat_processus)  
                     .s_liste_variables_partagees).nombre_variables_allouees)  
             {              {
                 (*(*s_etat_processus).s_liste_variables_partagees)                  (*s_etat_processus).erreur_systeme = d_es_processus;
                         .nombre_variables_allouees *= 2;                  return(d_erreur);
             }              }
   
               (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
               return(d_erreur);
         }          }
   
         if ((s_nouvelle_base = realloc((struct_variable_partagee *)          (**(*s_etat_processus).s_arbre_variables_partagees).feuille = NULL;
                 (*(*s_etat_processus).s_liste_variables_partagees).table,          (**(*s_etat_processus).s_arbre_variables_partagees)
                 (*(*s_etat_processus).s_liste_variables_partagees)                  .noeuds_utilises = 0;
                 .nombre_variables_allouees *          (**(*s_etat_processus).s_arbre_variables_partagees).indice_tableau_pere
                 sizeof(struct_variable_partagee))) == NULL)                  = -1;
           (**(*s_etat_processus).s_arbre_variables_partagees).noeud_pere = NULL;
           INITIALISATION_MUTEX((**(*s_etat_processus).s_arbre_variables_partagees)
                   .mutex_feuille);
   
           if (((**(*s_etat_processus).s_arbre_variables_partagees).noeuds =
                   allocation_tableau_noeuds_partages(s_etat_processus)) == NULL)
         {          {
               if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return(d_erreur);
               }
   
             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
             (*(*s_etat_processus).s_liste_variables_partagees)  
                     .nombre_variables--;  
             return(d_erreur);              return(d_erreur);
         }          }
   
         (*(*s_etat_processus).s_liste_variables_partagees).table =          for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
                 s_nouvelle_base;          {
               (**(*s_etat_processus).s_arbre_variables_partagees).noeuds[i] =
                       NULL;
           }
     }      }
   
     /*      l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
      * Positionnement de la variable partagée au bon endroit      ptr = (*s_variable).nom;
      */  
   
     if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables      if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
             == 1)  
     {      {
         (*(*s_etat_processus).s_liste_variables_partagees).table[0]          if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
                 = (*s_variable);          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
     }      }
     else  
       while((*ptr) != d_code_fin_chaine)
     {      {
         for(i = (*(*s_etat_processus).s_liste_variables_partagees)          BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
                 .nombre_variables - 2; i >= 0; i--)                  uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
                   *ptr));
   
           if ((*l_variable_courante).noeuds[(*s_etat_processus)
                   .pointeurs_caracteres_variables[*ptr]] == NULL)
         {          {
             if (strcmp((*s_variable).nom, (*(*s_etat_processus)              // Le noeud n'existe pas encore, on le crée et on le marque
                     .s_liste_variables_partagees).table[i].nom) < 0)              // comme utilisé dans la structure parente.
   
               if (((*l_variable_courante).noeuds[(*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr]] =
                       allocation_noeud_partage(s_etat_processus)) == NULL)
             {              {
                 (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1]                  if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
                         = (*(*s_etat_processus).s_liste_variables_partagees)                  {
                         .table[i];                      (*s_etat_processus).erreur_systeme = d_es_processus;
                       return(d_erreur);
                   }
   
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return(d_erreur);
             }              }
             else  
               (*l_variable_courante).noeuds_utilises++;
   
               // La feuille est par défaut vide et aucun élément du tableau noeuds
               // (les branches qui peuvent être issues de ce nouveau noeud)
               // n'est encore utilisée.
   
               (*(*l_variable_courante).noeuds[(*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
               (*(*l_variable_courante).noeuds[(*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
   
               // Le champ noeud_pere de la structure créée pointe sur
               // la structure parente et l'indice tableau_pere correspond à la
               // position réelle dans le tableau noeuds[] de la structure parente
               // du noeud courant. Cette valeur sera utilisée lors de la
               // destruction du noeud pour annuler le pointeur contenu dans
               // le tableau noeuds[] de la structure parente.
   
               (*(*l_variable_courante).noeuds[(*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
                       l_variable_courante;
               (*(*l_variable_courante).noeuds[(*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr]])
                       .indice_tableau_pere = (*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr];
               INITIALISATION_MUTEX((*(*l_variable_courante).noeuds
                       [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
                       .mutex_feuille);
   
               // Allocation du tableau noeuds[] et initialisation à zéro de
               // tous les pointeurs.
   
               if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
                       .pointeurs_caracteres_variables[*ptr]]).noeuds =
                       allocation_tableau_noeuds_partages(s_etat_processus))
                       == NULL)
               {
                   if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
                   {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return(d_erreur);
                   }
   
                   (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   return(d_erreur);
               }
   
               for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
             {              {
                 break;                  (*(*l_variable_courante).noeuds[(*s_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
                           = NULL;
             }              }
         }          }
   
         (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1]          if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds
                 = (*s_variable);                  [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
                   .mutex_feuille)) != 0)
           {
               if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return(d_erreur);
               }
   
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
           if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
           {
               if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return(d_erreur);
               }
   
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
           l_variable_courante = (*l_variable_courante).noeuds
                   [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
           ptr++;
       }
   
       if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
               == NULL)
       {
           if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
           (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
           return(d_erreur);
       }
   
       // Dans la feuille de l'arbre des variables partagées, on ne balaie
       // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
       // pour sauvegarder une référence vers la liste des variables partagées
       // pour pouvoir purger l'élément en cas de besoin.
   
       (*l_nouvel_element).suivant = (*l_variable_courante).feuille;
       (*l_nouvel_element).precedent = NULL;
   
       if ((*l_nouvel_element).suivant != NULL)
       {
           (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
       }
   
       (*l_nouvel_element).reference =
               (*(*s_etat_processus).l_liste_variables_partagees);
       (*l_nouvel_element).variable = (**(*s_etat_processus)
               .l_liste_variables_partagees).variable;
       (*l_variable_courante).feuille = l_nouvel_element;
       (*l_nouvel_element).feuille = l_variable_courante;
   
       if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
       {
           if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
     }      }
   
     return d_absence_erreur;      if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
       }
   
       return(d_absence_erreur);
 }  }
   
   
 /*  /*
 ================================================================================  ================================================================================
   Procédure de retrait d'une variable partagee de la base    Routine de recherche d'une variable partagée
 ================================================================================  ================================================================================
   Entrée :    Entrée :
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Sortie :    Sortie :
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Effets de bord : néant    Effets de bords : positionne le mutex sur la variable partagée
 ================================================================================  ================================================================================
 */  */
   
 logical1  struct_liste_variables_partagees *
 retrait_variable_partagee(struct_processus *s_etat_processus,  recherche_variable_partagee(struct_processus *s_etat_processus,
         unsigned char *nom_variable, union_position_variable position)          unsigned char *nom_variable, union_position_variable position,
           unsigned char origine)
 {  {
     struct_variable_partagee        *s_nouvelle_base;      int                                 pointeur;
   
     logical1                        erreur;      struct_arbre_variables_partagees    *l_variable_courante;
       struct_liste_variables_partagees    *l_element_courant;
   
     unsigned long                   position_courante;      unsigned char                       *ptr;
     unsigned long                   position_supprimee;  
   
     if (recherche_variable_partagee(s_etat_processus, nom_variable,      l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
             position, ((*s_etat_processus).mode_execution_programme == 'Y')      ptr = nom_variable;
             ? 'P' : 'E') == d_vrai)  
       if (l_variable_courante == NULL)
     {      {
         if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables          (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                 < ((*(*s_etat_processus).s_liste_variables_partagees)          return(NULL);
                 .nombre_variables_allouees / 2))      }
         {  
             (*(*s_etat_processus).s_liste_variables_partagees)  
                     .nombre_variables_allouees /= 2;  
   
             if ((s_nouvelle_base = realloc((struct_variable_partagee *)      if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
                     (*(*s_etat_processus).s_liste_variables_partagees).table,      {
                     (*(*s_etat_processus).s_liste_variables_partagees)          (*s_etat_processus).erreur_systeme = d_es_processus;
                     .nombre_variables_allouees *          return(NULL);
                     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 =      while((*ptr) != d_code_fin_chaine)
                     s_nouvelle_base;      {
           pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
   
           if (pointeur < 0)
           {
               // Caractère hors de l'alphabet des variables
   
               pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
               (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
               return(NULL);
         }          }
   
         position_supprimee = (*(*s_etat_processus)          if ((*l_variable_courante).noeuds[pointeur] == NULL)
                 .s_liste_variables_partagees).position_variable;          {
               // Le chemin de la variable candidate n'existe pas.
   
         liberation(s_etat_processus, (*(*s_etat_processus)              pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
                 .s_liste_variables_partagees).table[position_supprimee].objet);              (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
         free((*(*s_etat_processus).s_liste_variables_partagees)              return(NULL);
                 .table[position_supprimee].nom);          }
   
         (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables--;          if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
                   .mutex_feuille)) != 0)
           {
               pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(NULL);
           }
   
         for(position_courante = position_supprimee; position_courante <          if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
                 (*(*s_etat_processus).s_liste_variables_partagees)  
                 .nombre_variables; position_courante++)  
         {          {
             (*(*s_etat_processus).s_liste_variables_partagees).table              (*s_etat_processus).erreur_systeme = d_es_processus;
                     [position_courante] = (*(*s_etat_processus)              return(NULL);
                     .s_liste_variables_partagees).table[position_courante + 1];  
         }          }
   
         erreur = d_absence_erreur;          l_variable_courante = (*l_variable_courante).noeuds[pointeur];
           ptr++;
     }      }
     else  
       if ((*l_variable_courante).feuille != NULL)
     {      {
         erreur = d_erreur;          // Il existe au moins une variable partagée du nom requis.
         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;  
           l_element_courant = (*l_variable_courante).feuille;
   
           while(l_element_courant != NULL)
           {
               if ((*(*l_element_courant).variable).origine == 'P')
               {
                   if (((*(*l_element_courant).variable).variable_partagee.adresse
                           == position.adresse) &&
                           ((*(*l_element_courant).variable).origine == origine))
                   {
                       if (pthread_mutex_lock(&((*(*l_element_courant).variable)
                               .mutex)) != 0)
                       {
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           return(NULL);
                       }
   
                       if (pthread_mutex_unlock(&((*l_variable_courante)
                               .mutex_feuille)) != 0)
                       {
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           return(NULL);
                       }
   
                       (*s_etat_processus).pointeur_variable_partagee_courante
                               = (*l_element_courant).variable;
                       return(l_element_courant);
                   }
               }
               else
               {
                   if (((*(*l_element_courant).variable).variable_partagee.pointeur
                           == position.pointeur) &&
                           ((*(*l_element_courant).variable).origine == origine))
                   {
                       if (pthread_mutex_lock(&((*(*l_element_courant).variable)
                               .mutex)) != 0)
                       {
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           return(NULL);
                       }
   
                       if (pthread_mutex_unlock(&((*l_variable_courante)
                               .mutex_feuille)) != 0)
                       {
                           (*s_etat_processus).erreur_systeme = d_es_processus;
                           return(NULL);
                       }
   
                       (*s_etat_processus).pointeur_variable_partagee_courante
                               = (*l_element_courant).variable;
                       return(l_element_courant);
                   }
               }
   
               l_element_courant = (*l_element_courant).suivant;
           }
     }      }
   
     return erreur;      if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(NULL);
       }
   
       (*s_etat_processus).pointeur_variable_statique_courante = NULL;
       return(NULL);
 }  }
   
   
 /*  /*
 ================================================================================  ================================================================================
   Procédure de recherche d'une variable partagee par son nom dans la base    Routine de retrait d'une variable partagée
 ================================================================================  ================================================================================
   Entrée :    Entrée :
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Sortie :    Sortie :
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
   Effets de bord : néant    Effets de bords : néant
 ================================================================================  ================================================================================
 */  */
   
 logical1  logical1
 recherche_variable_partagee(struct_processus *s_etat_processus,  retrait_variable_partagee(struct_processus *s_etat_processus,
         unsigned char *nom_variable, union_position_variable position,          unsigned char *nom_variable, union_position_variable position)
         unsigned char origine)  
 {  {
     logical1                    existence_variable;      struct_liste_variables_partagees        *l_element_a_supprimer;
       struct_liste_variables_partagees        *l_element_liste_a_supprimer;
   
     long                        difference;      logical1                                erreur;
     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)      if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus,
             .nombre_variables == 0)              nom_variable, position, ((*s_etat_processus)
               .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;          if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
         return d_faux;          {
     }              (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
     ordre_iteration = 0;          // (*s_etat_processus).pointeur_variable_partagee_courante
     nombre_iterations_maximal = ((unsigned long)          // pointe sur la variable à éliminer. Cette variable est celle qui
             (log((*(*s_etat_processus).s_liste_variables_partagees)          // est présente dans l'une des feuilles statiques de l'arbre des
             .nombre_variables) / log(2))) + 2;          // variables.
   
     borne_inferieure = 0;          l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
     borne_superieure = (*(*s_etat_processus).s_liste_variables_partagees)  
             .nombre_variables - 1;  
   
     do          // Suppression de la liste des variables statiques
     {  
         moyenne = (borne_inferieure + borne_superieure) / 2;  
         ordre_iteration++;  
   
         if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2)))          if ((*l_element_liste_a_supprimer).precedent != NULL)
                 == (borne_inferieure + borne_superieure))  
         {          {
             difference = strcmp(nom_variable,              // L'élément à supprimer n'est pas le premier de la liste.
                     (*(*s_etat_processus).s_liste_variables_partagees)  
                     .table[moyenne].nom);  
   
             if (difference != 0)              (*(*l_element_liste_a_supprimer).precedent).suivant =
                       (*l_element_liste_a_supprimer).suivant;
   
               if ((*l_element_liste_a_supprimer).suivant != NULL)
             {              {
                 if (difference > 0)                  // Il y a un élément suivant. On le chaîne.
                 {                  (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
                     borne_inferieure = moyenne;  
                 }  
                 else  
                 {  
                     borne_superieure = moyenne;  
                 }  
             }              }
         }          }
         else          else
         {          {
             difference_inferieure = strcmp(nom_variable,              // L'élement est le premier de la liste. S'il y a un élément
                     (*(*s_etat_processus).s_liste_variables_partagees).table              // suivant, on le chaîne.
                     [moyenne].nom);  
             difference_superieure = strcmp(nom_variable,  
                     (*(*s_etat_processus).s_liste_variables_partagees).table  
                     [moyenne + 1].nom);  
   
             if (difference_inferieure == 0)              if ((*l_element_liste_a_supprimer).suivant != NULL)
             {              {
                 difference = 0;                  (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
             }              }
             else if (difference_superieure == 0)  
             {  
                 difference = 0;  
                 moyenne++;  
             }  
             else  
             {  
                 difference = difference_inferieure;  
   
                 if (difference > 0)              (*(*s_etat_processus).l_liste_variables_partagees) =
                 {                      (*l_element_liste_a_supprimer).suivant;
                     borne_inferieure = moyenne;  
                 }  
                 else  
                 {  
                     borne_superieure = moyenne;  
                 }  
             }  
         }          }
     } while((difference != 0) &&  
             (ordre_iteration <= nombre_iterations_maximal));  
   
     if (ordre_iteration > nombre_iterations_maximal)          free(l_element_liste_a_supprimer);
     {  
         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]          // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
                 .origine == 'P')          // pas car la liste est simplement chaînée.
   
           if ((*l_element_a_supprimer).precedent != NULL)
         {          {
             if (((*(*s_etat_processus).s_liste_variables_partagees)              // L'élément n'est pas le premier de la liste.
                     .table[moyenne].variable_partagee.adresse ==  
                     position.adresse) && ((*(*s_etat_processus)              (*(*l_element_a_supprimer).precedent).suivant =
                     .s_liste_variables_partagees).table[moyenne]                      (*l_element_a_supprimer).suivant;
                     .origine == origine))  
               if ((*l_element_a_supprimer).suivant != NULL)
             {              {
                 existence_variable = d_vrai;                  (*(*l_element_a_supprimer).suivant).precedent =
                           (*l_element_a_supprimer).precedent;
             }              }
             else              else
             {              {
                 existence_variable = d_faux;                  (*(*l_element_a_supprimer).precedent).suivant = NULL;
             }              }
         }          }
         else          else
         {          {
             if (((*(*s_etat_processus).s_liste_variables_partagees)              // L'élément est le premier de la liste.
                     .table[moyenne].variable_partagee.pointeur ==  
                     position.pointeur) && ((*(*s_etat_processus)              if ((*l_element_a_supprimer).suivant != NULL)
                     .s_liste_variables_partagees).table[moyenne]  
                     .origine == origine))  
             {  
                 existence_variable = d_vrai;  
             }  
             else  
             {              {
                 existence_variable = d_faux;                  (*(*l_element_a_supprimer).suivant).precedent = NULL;
             }              }
   
               (*(*l_element_a_supprimer).feuille).feuille
                       = (*l_element_a_supprimer).suivant;
         }          }
   
         if (existence_variable == d_faux)          liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
                   .objet);
           free((*(*l_element_a_supprimer).variable).nom);
           pthread_mutex_unlock(&((*(*l_element_a_supprimer).variable).mutex));
           pthread_mutex_destroy(&((*(*l_element_a_supprimer).variable).mutex));
           free((*l_element_a_supprimer).variable);
           free(l_element_a_supprimer);
   
           if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
         {          {
             // On rembobine.              (*s_etat_processus).erreur_systeme = d_es_processus;
               return(d_erreur);
           }
   
             if (moyenne > 0)          erreur = d_absence_erreur;
             {      }
                 while(strcmp(nom_variable, (*(*s_etat_processus)      else
                         .s_liste_variables_partagees).table[moyenne - 1].nom)      {
                         == 0)          erreur = d_erreur;
                 {          (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                     moyenne--;      }
   
       return(erreur);
   }
   
                     if (moyenne == 0)  
                     {  
                         break;  
                     }  
                 }  
             }  
   
             // Un petit test pour voir si le premier élément du tableau  /*
             // peut correspondre au critère de recherche.  ================================================================================
     Routine de retrait des variables partagées
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : néant
   ================================================================================
   */
   
   // Cette routine libère toutes les variables partagées de niveau non
   // nul, donc attachées à une expression et non un programme.
   
             existence_variable = d_faux;  logical1
   retrait_variables_partagees_locales(struct_processus *s_etat_processus)
   {
       struct_liste_variables_partagees    *l_element_courant;
       struct_liste_variables_partagees    *l_element_suivant;
   
       unsigned char                       registre_mode_execution;
   
       if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
       }
   
             if (strcmp((*(*s_etat_processus).s_liste_variables_partagees).table      registre_mode_execution = (*s_etat_processus).mode_execution_programme;
                     [moyenne].nom, nom_variable) == 0)      l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
   
       while(l_element_courant != NULL)
       {
           l_element_suivant = (*l_element_courant).suivant;
   
           (*s_etat_processus).mode_execution_programme =
                   ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
   
           if (((*(*l_element_courant).variable).niveau > 0) &&
                   ((*l_element_courant).pid == getpid()) &&
                   (pthread_equal((*l_element_courant).tid, pthread_self()) != 0))
           {
               if (retrait_variable_partagee(s_etat_processus,
                       (*(*l_element_courant).variable).nom,
                       (*(*l_element_courant).variable).variable_partagee)
                       == d_erreur)
             {              {
                 if ((*(*s_etat_processus).s_liste_variables_partagees).table                  if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
                         [moyenne].origine == 'P')  
                 {                  {
                     if (((*(*s_etat_processus).s_liste_variables_partagees)                      (*s_etat_processus).erreur_systeme = d_es_processus;
                             .table[moyenne].variable_partagee.adresse                      return(d_erreur);
                             == 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;  
                     }  
                 }                  }
   
                   (*s_etat_processus).mode_execution_programme =
                           registre_mode_execution;
                   return(d_erreur);
             }              }
           }
   
             // Puis on balaye dans le sens croissant.          l_element_courant = l_element_suivant;
       }
   
             if (((moyenne + 1) < (*(*s_etat_processus)      (*s_etat_processus).mode_execution_programme = registre_mode_execution;
                     .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)      if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
                             .table[moyenne].origine == 'P')      {
                     {          (*s_etat_processus).erreur_systeme = d_es_processus;
                         if (((*(*s_etat_processus).s_liste_variables_partagees)          return(d_erreur);
                                 .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)      return(d_absence_erreur);
                             .s_liste_variables_partagees).nombre_variables)  }
                     {  
                         break;  
                     }  /*
                 }  ================================================================================
             }    Routine de libération de l'arbre des variables partagées
         }  ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : positionne le mutex sur la variable partagée
   ================================================================================
   */
   
   void
   liberation_arbre_variables_partagees(struct_processus *s_etat_processus,
           struct_arbre_variables_partagees *arbre)
   {
       int                                 i;
   
       struct_liste_variables_partagees    *l_element_partage_courant;
       struct_liste_variables_partagees    *l_element_partage_suivant;
   
       // Libération de l'arbre des variables. Le contenu des variables n'est
       // pas détruit par cette opération, il sera détruit lors de la libération
       // de la liste des variables par niveau.
   
         (*(*s_etat_processus).s_liste_variables_partagees).position_variable      if (arbre == NULL)
                 = moyenne;      {
           return;
     }      }
   
     /*      if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0)
      * 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          (*s_etat_processus).erreur_systeme = d_es_processus;
      * du thread courant.          return;
      */      }
   
     if (existence_variable == d_faux)      l_element_partage_courant = (*arbre).feuille;
   
       while(l_element_partage_courant != NULL)
     {      {
         if (retrait_variable(s_etat_processus, nom_variable, 'L') == d_faux)          l_element_partage_suivant = (*l_element_partage_courant).suivant;
   
           if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable)
                   .mutex)) != 0)
         {          {
             return d_faux;              (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
         }          }
   
           free((*(*l_element_partage_courant).variable).nom);
           liberation(s_etat_processus, (*(*l_element_partage_courant)
                   .variable).objet);
           free((*l_element_partage_courant).variable);
   
           if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable)
                   .mutex)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable)
                   .mutex)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           free(l_element_partage_courant);
   
           l_element_partage_courant = l_element_partage_suivant;
       }
   
       for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
       {
           if ((*arbre).noeuds[i] != NULL)
           {
               liberation_arbre_variables_partagees(s_etat_processus,
                       (*arbre).noeuds[i]);
               (*arbre).noeuds[i] = NULL;
           }
       }
   
       liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds);
       liberation_noeud_partage(s_etat_processus, arbre);
   
       if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
     }      }
   
     return existence_variable;      arbre = NULL;
       return;
 }  }
   
 // vim: ts=4  // vim: ts=4

Removed from v.1.8  
changed lines
  Added in v.1.72


CVSweb interface <joel.bertrand@systella.fr>