Diff for /rpl/src/gestion_variables_partagees.c between versions 1.38 and 1.39

version 1.38, 2012/12/14 14:19:49 version 1.39, 2012/12/17 21:22:43
Line 25 Line 25
   
 /*  /*
 ================================================================================  ================================================================================
   Routine de création d'une nouvelle variable partagee    Routine de gestion du cache des objets
 ================================================================================  ================================================================================
   Entrée :    Entrée :
 --------------------------------------------------------------------------------  --------------------------------------------------------------------------------
Line 35 Line 35
 ================================================================================  ================================================================================
 */  */
   
 logical1  static inline struct_arbre_variables_partagees *
 creation_variable_partagee(struct_processus *s_etat_processus,  allocation_noeud_partage(struct_processus *s_etat_processus)
         struct_variable_partagee *s_variable)  
 {  {
     BUG(1);      struct_arbre_variables_partagees            *objet;
     return(d_absence_erreur);  
 }  
   
 logical1      if ((*s_etat_processus).pointeur_variables_partagees_noeud > 0)
 retrait_variable_partagee(struct_processus *s_etat_processus,      {
         unsigned char *nom_variable, union_position_variable position)          objet = (*s_etat_processus).variables_partagees_noeud
 {                  [--(*s_etat_processus).pointeur_variables_partagees_noeud];
     BUG(1);      }
     return(d_absence_erreur);      else
       {
           objet = malloc(sizeof(struct_arbre_variables_partagees));
       }
   
       return(objet);
 }  }
   
 logical1  static inline void
 retrait_variables_partagees_locales(struct_processus *s_etat_processus)  liberation_noeud_partage(struct_processus *s_etat_processus,
           struct_arbre_variables_partagees *objet)
 {  {
     BUG(1);      if ((*s_etat_processus).pointeur_variables_partagees_noeud < TAILLE_CACHE)
     return(d_absence_erreur);      {
           (*s_etat_processus).variables_partagees_noeud
                   [(*s_etat_processus).pointeur_variables_partagees_noeud++] =
                   objet;
       }
       else
       {
           free(objet);
       }
   
       return;
 }  }
   
 logical1  static inline struct_arbre_variables_partagees **
 recherche_variable_partagee(struct_processus *s_etat_processus,  allocation_tableau_noeuds_partages(struct_processus *s_etat_processus)
         unsigned char *nom_variable, union_position_variable position,  
         unsigned char origine)  
 {  {
     BUG(1);      struct_arbre_variables_partagees            **objet;
     return(d_faux);  
       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((*s_etat_processus).nombre_caracteres_variables
                   * sizeof(struct_arbre_variables_partagees *));
       }
   
       return(objet);
 }  }
   
 void  static inline void
 liberation_arbre_variables_partagees(struct_processus *s_etat_processus,  liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
         struct_arbre_variables *arbre)          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;      return;
 }  }
   
 #if 0  
   /*
   ================================================================================
     Routine de création d'une nouvelle variable partagee
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : néant
   ================================================================================
   */
   
 logical1  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;
   
       struct_arbre_variables_partagees        *l_variable_courante;
   
     long                                i;      struct_liste_variables_partagees        *l_nouvel_element;
   
     (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables++;      unsigned char                           *ptr;
   
     if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables >      // Ajout de la variable en tête de la liste des variables partagées
             (*(*s_etat_processus).s_liste_variables_partagees)  
             .nombre_variables_allouees)      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];
   
               // 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)
             {              {
                 break;                  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++)
               {
                   (*(*l_variable_courante).noeuds[(*s_etat_processus)
                           .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
                           = NULL;
               }
           }
   
           if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds
                   [(*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).s_liste_variables_partagees).table[i + 1]          (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                 = (*s_variable);          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;
     }      }
   
     return d_absence_erreur;      (*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);
       }
   
       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;
   
       struct_arbre_variables_partagees    *l_variable_courante;
       struct_liste_variables_partagees    *l_element_courant;
   
     logical1                        erreur;      unsigned char                       *ptr;
   
     unsigned long                   position_courante;      l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
     unsigned long                   position_supprimee;      ptr = nom_variable;
   
     if (recherche_variable_partagee(s_etat_processus, nom_variable,      if (l_variable_courante == NULL)
             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).erreur_systeme = d_es_variable_introuvable;
                 < ((*(*s_etat_processus).s_liste_variables_partagees)          return(NULL);
                 .nombre_variables_allouees / 2))      }
   
       if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(NULL);
       }
   
       while((*ptr) != d_code_fin_chaine)
       {
           pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
   
           if (pointeur < 0)
         {          {
             (*(*s_etat_processus).s_liste_variables_partagees)              // Caractère hors de l'alphabet des variables
                     .nombre_variables_allouees /= 2;  
   
             if ((s_nouvelle_base = realloc((struct_variable_partagee *)              (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
                     (*(*s_etat_processus).s_liste_variables_partagees).table,              return(NULL);
                     (*(*s_etat_processus).s_liste_variables_partagees)          }
                     .nombre_variables_allouees *  
                     sizeof(struct_variable_partagee))) == NULL)          if ((*l_variable_courante).noeuds[pointeur] == NULL)
             {          {
                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;              // Le chemin de la variable candidate n'existe pas.
                 return(d_erreur);              (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
             }              return(NULL);
           }
   
           if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
                   .mutex_feuille)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(NULL);
           }
   
             (*(*s_etat_processus).s_liste_variables_partagees).table =          if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
                     s_nouvelle_base;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return(NULL);
         }          }
   
         position_supprimee = (*(*s_etat_processus)          l_variable_courante = (*l_variable_courante).noeuds[pointeur];
                 .s_liste_variables_partagees).position_variable;          ptr++;
       }
   
         liberation(s_etat_processus, (*(*s_etat_processus)      if ((*l_variable_courante).feuille != NULL)
                 .s_liste_variables_partagees).table[position_supprimee].objet);      {
         free((*(*s_etat_processus).s_liste_variables_partagees)          // Il existe au moins une variable statique du nom requis.
                 .table[position_supprimee].nom);  
   
         (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables--;          l_element_courant = (*l_variable_courante).feuille;
   
         for(position_courante = position_supprimee; position_courante <          while(l_element_courant != NULL)
                 (*(*s_etat_processus).s_liste_variables_partagees)  
                 .nombre_variables; position_courante++)  
         {          {
             (*(*s_etat_processus).s_liste_variables_partagees).table              if ((*(*l_element_courant).variable).origine == 'P')
                     [position_courante] = (*(*s_etat_processus)              {
                     .s_liste_variables_partagees).table[position_courante + 1];                  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);
                       }
   
         erreur = d_absence_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_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;
           }
     }      }
     else  
       if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
     {      {
         erreur = d_erreur;          (*s_etat_processus).erreur_systeme = d_es_processus;
         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;          return(NULL);
     }      }
   
     return erreur;      (*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;          // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;          // pas car la liste est simplement chaînée.
     }  
     else  
     {  
         // Reste à rechercher la variable déclarée à la position 'position'...  
   
         if ((*(*s_etat_processus).s_liste_variables_partagees).table[moyenne]          if ((*l_element_a_supprimer).precedent != NULL)
                 .origine == 'P')  
         {          {
             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);
           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--;      }
   
                     if (moyenne == 0)      return(erreur);
                     {  }
                         break;  
                     }  
                 }  /*
             }  ================================================================================
     Routine de retrait des variables partagées
   ================================================================================
     Entrée :
   --------------------------------------------------------------------------------
     Sortie :
   --------------------------------------------------------------------------------
     Effets de bords : néant
   ================================================================================
   */
   
             // Un petit test pour voir si le premier élément du tableau  // Cette routine libère toutes les variables partagées de niveau non
             // peut correspondre au critère de recherche.  // 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;
   
             if (strcmp((*(*s_etat_processus).s_liste_variables_partagees).table      unsigned char                       registre_mode_execution;
                     [moyenne].nom, nom_variable) == 0)  
       if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return(d_erreur);
       }
   
       registre_mode_execution = (*s_etat_processus).mode_execution_programme;
       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;  
                     }  
                 }  
             }  
         }  
   
         (*(*s_etat_processus).s_liste_variables_partagees).position_variable  
                 = moyenne;  /*
   ================================================================================
     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.
   
       if (arbre == NULL)
       {
           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;
      */      }
   
       l_element_partage_courant = (*arbre).feuille;
   
     if (existence_variable == d_faux)      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;
     }      }
   
     return existence_variable;      if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
       arbre = NULL;
       return;
 }  }
 #endif  
 // vim: ts=4  // vim: ts=4

Removed from v.1.38  
changed lines
  Added in v.1.39


CVSweb interface <joel.bertrand@systella.fr>