--- rpl/src/gestion_variables.c 2011/06/19 17:48:27 1.33 +++ rpl/src/gestion_variables.c 2012/01/05 10:18:59 1.50 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.0.prerelease.0 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.5 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -46,9 +46,18 @@ liste_variables_par_niveaux(struct_proce struct_liste_chainee *e; - printf("===========================================================\n"); + printf("==========================================================" + "======================\n"); printf(" Liste des variables par niveaux\n"); - printf("===========================================================\n"); + printf("==========================================================" + "======================\n"); + + if ((*s_etat_processus).l_liste_variables_par_niveau == NULL) + { + printf("==========================================================" + "======================\n"); + return; + } printf("Backward\n"); l = (*s_etat_processus).l_liste_variables_par_niveau; @@ -62,8 +71,8 @@ liste_variables_par_niveaux(struct_proce while(e != NULL) { - printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom, - e->donnee, ((struct_variable *) e->donnee)->niveau); + printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom, + e, e->donnee, ((struct_variable *) e->donnee)->niveau); e = e->suivant; c++; if (c > 100) @@ -87,8 +96,8 @@ liste_variables_par_niveaux(struct_proce while(e != NULL) { - printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom, - e->donnee, ((struct_variable *) e->donnee)->niveau); + printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom, + e, e->donnee, ((struct_variable *) e->donnee)->niveau); e = e->suivant; c++; if (c > 100) exit(0); @@ -99,7 +108,8 @@ liste_variables_par_niveaux(struct_proce l = l->suivant; } while(l != (*s_etat_processus).l_liste_variables_par_niveau); - printf("===========================================================\n"); + printf("==========================================================" + "======================\n"); if (fin == d_vrai) exit(0); @@ -119,9 +129,30 @@ liste_variables_tas(struct_processus *s_ fin = d_faux; + if (arbre == NULL) + { + return; + } + + printf(">>> Position : %d\n", + (*arbre).indice_tableau_pere); + printf(">>> Nombre de noeuds utilisés : %u\n", + (*arbre).noeuds_utilises); + printf(">>> Noeuds fils : "); + + for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) + { + if ((*arbre).noeuds[i] != NULL) + { + printf("%d ", i); + } + } + + printf("\b\n"); + if ((*arbre).feuille != NULL) { - printf("Feuille %p\n", (*arbre).feuille); + printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises); printf(" Backward\n"); @@ -157,10 +188,14 @@ liste_variables_tas(struct_processus *s_ } while((*arbre).feuille != l); } + printf("----------------------------------------------------------" + "----------------------\n"); + for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) { if ((*arbre).noeuds[i] != NULL) { + liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]); } } @@ -174,14 +209,172 @@ liste_variables_tas(struct_processus *s_ static void liste_variables_par_feuilles(struct_processus *s_etat_processus) { - printf("===========================================================\n"); + printf("==========================================================" + "======================\n"); printf(" Liste des variables sur le tas\n"); - printf("===========================================================\n"); + printf("==========================================================" + "======================\n"); liste_variables_tas(s_etat_processus, (*s_etat_processus).s_arbre_variables); - printf("===========================================================\n"); + printf("==========================================================" + "======================\n"); + + return; +} + + +/* +================================================================================ + 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; } @@ -226,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); @@ -238,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); @@ -258,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) @@ -269,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); @@ -306,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); @@ -334,13 +525,15 @@ 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); } + (*l_variable_courante).noeuds_utilises++; + (*(*l_variable_courante).feuille).suivant = (*l_variable_courante).feuille; (*(*l_variable_courante).feuille).precedent = @@ -351,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); @@ -363,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; @@ -380,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. @@ -396,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); @@ -420,19 +613,27 @@ 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) && ((*(*l_variable_candidate).variable).niveau <= 1)); + BUG((*s_variable).niveau == 0, + uprintf("Attempt to create a level-0 variable!\n")); + if ((*(*(*(*l_variable_courante).feuille).precedent).variable) .niveau > 1) { - // Ajout inconditionnel des variables de niveaux 0 et 1 + // La variable précédente est de niveau strictement supérieur + // à 1. Il ne peut donc y avoir aucune variable de niveau + // inférieur ou égal à 1 puisque la boucle est triée. + // On insère donc directement la variable en queue. } else { + // Le niveau de la variable précédente dans la boucle est + // inférieur ou égal à 1. l_variable_candidate = (*(*l_variable_courante).feuille) .precedent; } @@ -445,8 +646,19 @@ ajout_variable(struct_processus *s_etat_ (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable; (*l_variable_candidate).precedent = l_nouvelle_variable; + // Si la variable suivant la variable que l'on vient d'insérer + // dans la boucle est de niveau 0, la variable insérée est par + // construction de niveau 1 et il convient de modifier le + // pointeur de feuille pointant sur l'élément de plus haut niveau + // de la boucle. + + if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0) + { + (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable; + } + 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); @@ -465,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; @@ -481,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); @@ -499,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; @@ -521,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); @@ -561,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; @@ -594,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); @@ -608,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); @@ -976,10 +1188,10 @@ retrait_variable(struct_processus *s_eta unsigned char *nom_variable, unsigned char type) { logical1 erreur; + logical1 variable_supprimee; struct_arbre_variables *s_arbre_a_supprimer; struct_arbre_variables *s_arbre_courant; - struct_arbre_variables *noeud_courant; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_precedent; @@ -989,6 +1201,8 @@ retrait_variable(struct_processus *s_eta unsigned long niveau; + (*s_etat_processus).niveau_supprime = d_faux; + if (recherche_variable(s_etat_processus, nom_variable) == d_vrai) { // Une variable correspondant au nom recherché est accessible. @@ -1069,15 +1283,15 @@ retrait_variable(struct_processus *s_eta variable_a_supprimer = (*s_etat_processus) .pointeur_feuille_courante; - s_arbre_courant = (*variable_a_supprimer).noeud_pere; - noeud_courant = (*variable_a_supprimer).noeud; - (*s_arbre_courant).noeuds[(*noeud_courant).indice_tableau_pere] - = NULL; - + s_arbre_courant = (*variable_a_supprimer).noeud; BUG((*s_arbre_courant).noeuds_utilises == 0, uprintf("Freed node !\n")); (*s_arbre_courant).noeuds_utilises--; + (*((*(*variable_a_supprimer).noeud_pere).noeuds + [(*(*variable_a_supprimer).noeud).indice_tableau_pere])) + .feuille = NULL; + while((*s_arbre_courant).noeuds_utilises == 0) { s_arbre_a_supprimer = s_arbre_courant; @@ -1085,8 +1299,11 @@ 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; } @@ -1100,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")); @@ -1142,8 +1360,6 @@ retrait_variable(struct_processus *s_eta (*(*s_etat_processus).pointeur_feuille_courante).suivant; (*s_etat_processus).pointeur_variable_courante = (*(*s_etat_processus).pointeur_feuille_courante).variable; - - noeud_courant = NULL; } // Dans tous les cas, on retire la variable de la liste des variables @@ -1151,6 +1367,7 @@ retrait_variable(struct_processus *s_eta niveau = (*(*variable_a_supprimer).variable).niveau; variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau; + variable_supprimee = d_faux; if (variables_par_niveau != NULL) { @@ -1188,7 +1405,39 @@ 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) + { + (*s_etat_processus).niveau_supprime = + d_vrai; + + if ((*s_etat_processus) + .l_liste_variables_par_niveau + == variables_par_niveau) + { + // On retire l'élément de la liste + // pointé par + // l_liste_variable_par_niveau + + (*s_etat_processus) + .l_liste_variables_par_niveau = + (*variables_par_niveau).suivant; + } + + (*(*variables_par_niveau).precedent) + .suivant = + (*variables_par_niveau).suivant; + (*(*variables_par_niveau).suivant) + .precedent = + (*variables_par_niveau) + .precedent; + liberation_feuille(s_etat_processus, + variables_par_niveau); + } + + variable_supprimee = d_vrai; break; } @@ -1198,6 +1447,11 @@ retrait_variable(struct_processus *s_eta } } + if (variable_supprimee == d_vrai) + { + break; + } + variables_par_niveau = (*variables_par_niveau).suivant; } while(variables_par_niveau != (*s_etat_processus) @@ -1208,16 +1462,10 @@ 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; - - if (noeud_courant != NULL) - { - free((*noeud_courant).noeuds); - free(noeud_courant); - } } else { @@ -1280,6 +1528,8 @@ retrait_variable_par_niveau(struct_proce while((*(*s_etat_processus).l_liste_variables_par_niveau).liste != NULL) { + // Nécessaire car le pointeur sur la tête de la pile + // peut être modifié par retrait_variable(). // Sauvegarde des variables statiques. if ((*((struct_variable *) (*(*(*s_etat_processus) @@ -1367,6 +1617,17 @@ retrait_variable_par_niveau(struct_proce { return(d_erreur); } + + if ((*((struct_variable *) (*(*(*s_etat_processus) + .l_liste_variables_par_niveau).liste).donnee)).niveau + <= (*s_etat_processus).niveau_courant) + { + // On a retiré de l'arbre des variables toutes les + // variables de niveau strictement supérieur au niveau + // courant. + + return(d_absence_erreur); + } } } @@ -1381,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); @@ -1417,6 +1678,11 @@ liberation_arbre_variables(struct_proces // 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; + } + l_element_courant = (*arbre).feuille; if (l_element_courant != NULL) @@ -1424,9 +1690,11 @@ 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); + + (*arbre).feuille = NULL; } for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) @@ -1435,6 +1703,7 @@ liberation_arbre_variables(struct_proces { liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i], retrait_definitions); + (*arbre).noeuds[i] = NULL; } } @@ -1460,25 +1729,28 @@ liberation_arbre_variables(struct_proces (*l_element_courant_liste).donnee)).objet); free((*((struct_variable *) (*l_element_courant_liste) .donnee)).nom); - free((*l_element_courant_liste).donnee); } l_element_suivant_liste = (*l_element_courant_liste).suivant; - 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; } @@ -1573,6 +1845,7 @@ liste_variables(struct_processus *s_etat return(position); } + /* ================================================================================ Procédure de copie de l'arbre des variables @@ -1585,19 +1858,131 @@ liste_variables(struct_processus *s_etat ================================================================================ */ -struct_arbre_variables * -copie_arbre_variables(struct_processus *s_etat_processus) +void +copie_arbre_variables(struct_processus *s_etat_processus, struct_processus + *s_nouvel_etat_processus) { // Les définitions sont partagées entre tous les threads et ne sont pas // copiées. // // NB : on ne copie que les variables de niveaux 0 et 1, les autres // variables locales étant masquées par le processus de création de thread - // ou de processus, elles sont inaccessibles. + // ou de processus, elles seront inaccessibles de tous les points + // du fil d'exécution fils. - BUG(1, uprintf("Oops !\n")); + // Pour copier ces variables, on récupère les variables depuis la liste par + // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle + // structure. Les variables de niveau 0 étant non modifiables, elles + // ne sont pas dupliquées. - return(d_absence_erreur); + int i; + + logical1 niveau_0_traite; + logical1 niveau_1_traite; + + struct_liste_chainee *l_element_courant; + + struct_liste_variables *l_niveau_courant; + + struct_variable s_variable; + + (*s_nouvel_etat_processus).s_arbre_variables = NULL; + (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL; + + 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 niveau précédent la valeur courante dans la + // boucle. + + if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau + != 0) + { + l_niveau_courant = (*l_niveau_courant).precedent; + } + + // 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) + { + if (niveau_0_traite == d_faux) + { + l_element_courant = (*l_niveau_courant).liste; + + while(l_element_courant != NULL) + { + if (ajout_variable(s_nouvel_etat_processus, + (struct_variable *) (*l_element_courant).donnee) + == d_erreur) + { + return; + } + + l_element_courant = (*l_element_courant).suivant; + } + + niveau_0_traite = d_vrai; + } + } + else if ((*((struct_variable *) (*(*l_niveau_courant).liste) + .donnee)).niveau == 1) + { + if (niveau_1_traite == d_faux) + { + l_element_courant = (*l_niveau_courant).liste; + + while(l_element_courant != NULL) + { + s_variable = (*((struct_variable *) + (*l_element_courant).donnee)); + + 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 ((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; + } + + niveau_1_traite = d_vrai; + } + + // Les variables de niveau 0 ayant déjà été copiées, on + // peut sortir de la boucle car toutes les variables sont + // maintenant disponibles dans le fil d'exécution fils. + + break; + } + + l_niveau_courant = (*l_niveau_courant).precedent; + } + + return; }