--- rpl/src/gestion_variables.c 2011/06/21 15:26:29 1.39 +++ rpl/src/gestion_variables.c 2012/05/21 17:25:42 1.55 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.0.prerelease.2 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.9 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -227,6 +227,161 @@ liste_variables_par_feuilles(struct_proc /* ================================================================================ + Routine de gestion du cache mémoire sur l'arbre des variables +================================================================================ + Entrée : +-------------------------------------------------------------------------------- + Sortie : +-------------------------------------------------------------------------------- + Effets de bords : néant +================================================================================ +*/ + +static inline struct_arbre_variables * +allocation_noeud(struct_processus *s_etat_processus) +{ + struct_arbre_variables *objet; + + if ((*s_etat_processus).pointeur_variables_noeud > 0) + { + objet = (*s_etat_processus).variables_noeud + [--(*s_etat_processus).pointeur_variables_noeud]; + } + else + { + objet = malloc(sizeof(struct_arbre_variables)); + } + + return(objet); +} + +static inline void +liberation_noeud(struct_processus *s_etat_processus, + struct_arbre_variables *objet) +{ + if ((*s_etat_processus).pointeur_variables_noeud < TAILLE_CACHE) + { + (*s_etat_processus).variables_noeud + [(*s_etat_processus).pointeur_variables_noeud++] = objet; + } + else + { + free(objet); + } + + return; +} + +static inline struct_arbre_variables ** +allocation_tableau_noeuds(struct_processus *s_etat_processus) +{ + struct_arbre_variables **objet; + + if ((*s_etat_processus).pointeur_variables_tableau_noeuds > 0) + { + objet = (*s_etat_processus).variables_tableau_noeuds + [--(*s_etat_processus).pointeur_variables_tableau_noeuds]; + } + else + { + objet = malloc((*s_etat_processus).nombre_caracteres_variables + * sizeof(struct_arbre_variables *)); + } + + return(objet); +} + +static inline void +liberation_tableau_noeuds(struct_processus *s_etat_processus, + struct_arbre_variables **objet) +{ + if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE) + { + (*s_etat_processus).variables_tableau_noeuds + [(*s_etat_processus).pointeur_variables_tableau_noeuds++] = + objet; + } + else + { + free(objet); + } + + return; +} + +static inline struct_liste_variables * +allocation_feuille(struct_processus *s_etat_processus) +{ + struct_liste_variables *objet; + + if ((*s_etat_processus).pointeur_variables_feuille > 0) + { + objet = (*s_etat_processus).variables_feuille + [--(*s_etat_processus).pointeur_variables_feuille]; + } + else + { + objet = malloc(sizeof(struct_liste_variables)); + } + + return(objet); +} + +static inline void +liberation_feuille(struct_processus *s_etat_processus, + struct_liste_variables *objet) +{ + if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE) + { + (*s_etat_processus).variables_feuille + [(*s_etat_processus).pointeur_variables_feuille++] = objet; + } + else + { + free(objet); + } + + return; +} + +static inline struct_variable * +allocation_variable(struct_processus *s_etat_processus) +{ + struct_variable *objet; + + if ((*s_etat_processus).pointeur_variables_variable > 0) + { + objet = (*s_etat_processus).variables_variable + [--(*s_etat_processus).pointeur_variables_variable]; + } + else + { + objet = malloc(sizeof(struct_variable)); + } + + return(objet); +} + +static inline void +liberation_variable(struct_processus *s_etat_processus, + struct_variable *objet) +{ + if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE) + { + (*s_etat_processus).variables_variable + [(*s_etat_processus).pointeur_variables_variable++] = objet; + } + else + { + free(objet); + } + + return; +} + + +/* +================================================================================ Routine de création d'une nouvelle variable ================================================================================ Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'. @@ -264,7 +419,7 @@ ajout_variable(struct_processus *s_etat_ if ((*s_etat_processus).s_arbre_variables == NULL) { if (((*s_etat_processus).s_arbre_variables = - malloc(sizeof(struct_arbre_variables))) == NULL) + allocation_noeud(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -276,8 +431,7 @@ ajout_variable(struct_processus *s_etat_ (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL; if (((*(*s_etat_processus).s_arbre_variables).noeuds = - malloc((*s_etat_processus).nombre_caracteres_variables - * sizeof(struct_arbre_variables))) == NULL) + allocation_tableau_noeuds(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -296,7 +450,7 @@ ajout_variable(struct_processus *s_etat_ while((*ptr) != d_code_fin_chaine) { BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0, - printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom, + uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom, *ptr)); if ((*l_variable_courante).noeuds[(*s_etat_processus) @@ -307,7 +461,7 @@ ajout_variable(struct_processus *s_etat_ if (((*l_variable_courante).noeuds[(*s_etat_processus) .pointeurs_caracteres_variables[*ptr]] = - malloc(sizeof(struct_arbre_variables))) == NULL) + allocation_noeud(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -344,8 +498,7 @@ ajout_variable(struct_processus *s_etat_ if (((*(*l_variable_courante).noeuds[(*s_etat_processus) .pointeurs_caracteres_variables[*ptr]]).noeuds = - malloc((*s_etat_processus).nombre_caracteres_variables - * sizeof(struct_arbre_variables))) == NULL) + allocation_tableau_noeuds(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -372,8 +525,8 @@ ajout_variable(struct_processus *s_etat_ // variables de même nom. Cette liste boucle en premier lieu sur // elle-même. - if (((*l_variable_courante).feuille = malloc( - sizeof(struct_liste_variables))) == NULL) + if (((*l_variable_courante).feuille = allocation_feuille( + s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -391,7 +544,7 @@ ajout_variable(struct_processus *s_etat_ // Allocation de la variable sur l'élément de la liste. if (((*(*l_variable_courante).feuille).variable = - malloc(sizeof(struct_variable))) == NULL) + allocation_variable(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -403,7 +556,7 @@ ajout_variable(struct_processus *s_etat_ } else { - if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables))) + if ((l_nouvelle_variable = allocation_feuille(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -420,7 +573,7 @@ ajout_variable(struct_processus *s_etat_ BUG((*(*(*l_variable_courante).feuille).variable).niveau >= (*s_variable).niveau, - printf("Variable=\"%s\"\n", (*s_variable).nom)); + uprintf("Variable=\"%s\"\n", (*s_variable).nom)); // On ajoute la variable à la liste existante. @@ -436,7 +589,7 @@ ajout_variable(struct_processus *s_etat_ (*l_variable_courante).feuille = l_nouvelle_variable; if (((*(*l_variable_courante).feuille).variable = - malloc(sizeof(struct_variable))) == NULL) + allocation_variable(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -460,7 +613,7 @@ ajout_variable(struct_processus *s_etat_ BUG((*(*l_variable_candidate).variable).niveau == (*s_variable).niveau, - printf("Variable=\"%s\"\n", (*s_variable).nom)); + uprintf("Variable=\"%s\"\n", (*s_variable).nom)); l_variable_candidate = (*l_variable_candidate).precedent; } while((l_variable_candidate != (*l_variable_courante).feuille) && @@ -505,7 +658,7 @@ ajout_variable(struct_processus *s_etat_ } if (((*l_nouvelle_variable).variable = - malloc(sizeof(struct_variable))) == NULL) + allocation_variable(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -524,7 +677,7 @@ ajout_variable(struct_processus *s_etat_ { // Le niveau courant n'existe pas. Il est créé. - if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables))) + if ((l_nouvelle_variable = allocation_feuille(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -540,7 +693,7 @@ ajout_variable(struct_processus *s_etat_ // Ajout de la variable en tête de la liste - if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL) + if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -558,7 +711,7 @@ ajout_variable(struct_processus *s_etat_ { // Le niveau courant n'existe pas. Il est créé. - if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables))) + if ((l_nouvelle_variable = allocation_feuille(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -580,7 +733,7 @@ ajout_variable(struct_processus *s_etat_ // Ajout de la variable en tête de la liste - if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL) + if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -620,7 +773,7 @@ ajout_variable(struct_processus *s_etat_ if (niveau_acceptable == d_faux) { - if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables))) + if ((l_nouvelle_variable = allocation_feuille(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -653,7 +806,7 @@ ajout_variable(struct_processus *s_etat_ // Ajout de la variable en tête de la liste l_variable_candidate. - if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL) + if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -667,7 +820,7 @@ ajout_variable(struct_processus *s_etat_ { // Ajout de la variable en tête de la liste - if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL) + if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); @@ -1146,8 +1299,9 @@ retrait_variable(struct_processus *s_eta if (s_arbre_courant == NULL) { - free((*s_arbre_a_supprimer).noeuds); - free(s_arbre_a_supprimer); + liberation_tableau_noeuds(s_etat_processus, + (*s_arbre_a_supprimer).noeuds); + liberation_noeud(s_etat_processus, s_arbre_a_supprimer); (*s_etat_processus).s_arbre_variables = NULL; break; @@ -1163,8 +1317,9 @@ retrait_variable(struct_processus *s_eta (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer) .indice_tableau_pere] = NULL; - free((*s_arbre_a_supprimer).noeuds); - free(s_arbre_a_supprimer); + liberation_tableau_noeuds(s_etat_processus, + (*s_arbre_a_supprimer).noeuds); + liberation_noeud(s_etat_processus, s_arbre_a_supprimer); BUG((*s_arbre_courant).noeuds_utilises == 0, uprintf("Freed node !\n")); @@ -1250,7 +1405,8 @@ retrait_variable(struct_processus *s_eta (*l_element_courant).suivant; } - free(l_element_courant); + liberation_maillon(s_etat_processus, + l_element_courant); if ((*variables_par_niveau).liste == NULL) { @@ -1277,7 +1433,8 @@ retrait_variable(struct_processus *s_eta .precedent = (*variables_par_niveau) .precedent; - free(variables_par_niveau); + liberation_feuille(s_etat_processus, + variables_par_niveau); } variable_supprimee = d_vrai; @@ -1305,8 +1462,8 @@ retrait_variable(struct_processus *s_eta free((*(*variable_a_supprimer).variable).nom); liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet); - free((*variable_a_supprimer).variable); - free(variable_a_supprimer); + liberation_variable(s_etat_processus, (*variable_a_supprimer).variable); + liberation_feuille(s_etat_processus, variable_a_supprimer); erreur = d_absence_erreur; } @@ -1485,7 +1642,7 @@ retrait_variable_par_niveau(struct_proce .l_liste_variables_par_niveau; (*s_etat_processus).l_liste_variables_par_niveau = (*l_element_a_supprimer).suivant; - free(l_element_a_supprimer); + liberation_feuille(s_etat_processus, l_element_a_supprimer); } return(d_absence_erreur); @@ -1533,7 +1690,7 @@ liberation_arbre_variables(struct_proces do { l_element_suivant = (*l_element_courant).suivant; - free(l_element_courant); + liberation_feuille(s_etat_processus, l_element_courant); l_element_courant = l_element_suivant; } while(l_element_courant != (*arbre).feuille); @@ -1576,21 +1733,23 @@ liberation_arbre_variables(struct_proces l_element_suivant_liste = (*l_element_courant_liste).suivant; - free((*l_element_courant_liste).donnee); - free(l_element_courant_liste); + liberation_variable(s_etat_processus, (struct_variable *) + (*l_element_courant_liste).donnee); + liberation_maillon(s_etat_processus, + l_element_courant_liste); l_element_courant_liste = l_element_suivant_liste; } l_element_suivant = (*l_element_courant).suivant; - free(l_element_courant); + liberation_feuille(s_etat_processus, l_element_courant); l_element_courant = l_element_suivant; } while(l_element_courant != (*s_etat_processus) .l_liste_variables_par_niveau); } } - free((*arbre).noeuds); - free(arbre); + liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds); + liberation_noeud(s_etat_processus, arbre); arbre = NULL; return; @@ -1643,6 +1802,7 @@ nombre_variables(struct_processus *s_eta return(n); } + int liste_variables(struct_processus *s_etat_processus, struct_tableau_variables *tableau, int position, @@ -1686,6 +1846,7 @@ liste_variables(struct_processus *s_etat return(position); } + /* ================================================================================ Procédure de copie de l'arbre des variables @@ -1717,6 +1878,9 @@ copie_arbre_variables(struct_processus * int i; + logical1 niveau_0_traite; + logical1 niveau_1_traite; + struct_liste_chainee *l_element_courant; struct_liste_variables *l_niveau_courant; @@ -1729,7 +1893,7 @@ copie_arbre_variables(struct_processus * l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau; // Si la variable en tête n'est pas une variable de niveau 0, le niveau - // 0, s'il existe est le nivau précédent la valeur courante dans la + // 0, s'il existe est le niveau précédent la valeur courante dans la // boucle. if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau @@ -1741,59 +1905,72 @@ copie_arbre_variables(struct_processus * // Les variables de niveaux 0 et 1 sont accessibles en au plus trois // itérations (par construction). + niveau_0_traite = d_faux; + niveau_1_traite = d_faux; + for(i = 0; i <= 2; i++) { if ((*((struct_variable *) (*(*l_niveau_courant).liste) .donnee)).niveau == 0) { - l_element_courant = (*l_niveau_courant).liste; - - while(l_element_courant != NULL) + if (niveau_0_traite == d_faux) { - if (ajout_variable(s_nouvel_etat_processus, - (struct_variable *) (*l_element_courant).donnee) - == d_erreur) + l_element_courant = (*l_niveau_courant).liste; + + while(l_element_courant != NULL) { - return; + if (ajout_variable(s_nouvel_etat_processus, + (struct_variable *) (*l_element_courant).donnee) + == d_erreur) + { + return; + } + + l_element_courant = (*l_element_courant).suivant; } - l_element_courant = (*l_element_courant).suivant; + niveau_0_traite = d_vrai; } } else if ((*((struct_variable *) (*(*l_niveau_courant).liste) .donnee)).niveau == 1) { - l_element_courant = (*l_niveau_courant).liste; - - while(l_element_courant != NULL) + if (niveau_1_traite == d_faux) { - s_variable = (*((struct_variable *) - (*l_element_courant).donnee)); + l_element_courant = (*l_niveau_courant).liste; - if ((s_variable.nom = strdup((*((struct_variable *) - (*l_element_courant).donnee)).nom)) == NULL) + while(l_element_courant != NULL) { - (*s_nouvel_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } + s_variable = (*((struct_variable *) + (*l_element_courant).donnee)); - if ((s_variable.objet = copie_objet(s_nouvel_etat_processus, - (*((struct_variable *) (*l_element_courant).donnee)) - .objet, 'P')) == NULL) - { - (*s_nouvel_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } + if ((s_variable.nom = strdup((*((struct_variable *) + (*l_element_courant).donnee)).nom)) == NULL) + { + (*s_nouvel_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } - if (ajout_variable(s_nouvel_etat_processus, &s_variable) - == d_erreur) - { - return; + if ((s_variable.objet = copie_objet(s_nouvel_etat_processus, + (*((struct_variable *) (*l_element_courant).donnee)) + .objet, 'P')) == NULL) + { + (*s_nouvel_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + if (ajout_variable(s_nouvel_etat_processus, &s_variable) + == d_erreur) + { + return; + } + + l_element_courant = (*l_element_courant).suivant; } - l_element_courant = (*l_element_courant).suivant; + niveau_1_traite = d_vrai; } // Les variables de niveau 0 ayant déjà été copiées, on