--- rpl/src/gestion_objets.c 2010/08/06 15:26:45 1.33 +++ rpl/src/gestion_objets.c 2012/10/04 15:21:26 1.87 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.18 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.11 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -57,7 +57,7 @@ decrementation_atomique(struct_objet *s_ return((*s_objet).nombre_occurrences); } -inline void +void initialisation_objet(struct_objet *s_objet) { pthread_mutexattr_t attributs_mutex; @@ -111,6 +111,11 @@ initialisation_allocateur(struct_process (*s_etat_processus).pointeur_vec = 0; (*s_etat_processus).pointeur_maillons = 0; + (*s_etat_processus).pointeur_variables_noeud = 0; + (*s_etat_processus).pointeur_variables_feuille = 0; + (*s_etat_processus).pointeur_variables_variable = 0; + (*s_etat_processus).pointeur_variables_tableau_noeuds = 0; + return; } @@ -143,6 +148,15 @@ liberation_allocateur(struct_processus * for(i = 0; i < (*s_etat_processus).pointeur_maillons; free((*s_etat_processus).maillons[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_noeud; + free((*s_etat_processus).variables_noeud[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_feuille; + free((*s_etat_processus).variables_feuille[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_variable; + free((*s_etat_processus).variables_variable[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_tableau_noeuds; + free((*s_etat_processus).variables_tableau_noeuds[i++])); + { struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_suivant; @@ -234,7 +248,7 @@ allocation_maillon(struct_processus *s_e /* ================================================================================ - Routine d'allocation d'un maillon d'un objet (liste, expression...) + Routine de libération d'un maillon d'un objet (liste, expression...) ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- @@ -274,7 +288,7 @@ liberation_maillon(struct_processus *s_e ================================================================================ */ -void * +struct_objet * allocation(struct_processus *s_etat_processus, enum t_type type) { struct_objet *s_objet; @@ -530,6 +544,7 @@ allocation(struct_processus *s_etat_proc return(NULL); } + (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self(); break; } @@ -1089,6 +1104,28 @@ liberation(struct_processus *s_etat_proc return; } + if (pthread_mutex_trylock(&((*((struct_mutex *) + (*s_objet).objet)).mutex)) == 0) + { + // On a pu verrouiller le mutex. Il faut donc spécifier le tid. + (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self(); + } + + if (pthread_equal(pthread_self(), + (*((struct_mutex *) (*s_objet).objet)).tid) != 0) + { + pthread_mutex_unlock(&((*((struct_mutex *) + (*s_objet).objet)).mutex)); + } + else + { + (*s_etat_processus).erreur_systeme = + d_es_mutex_acquis_autre_thread; + return; + } + + pthread_mutex_destroy(&((*((struct_mutex *) + (*s_objet).objet)).mutex)); free((struct_mutex *) (*s_objet).objet); break; } @@ -1128,7 +1165,7 @@ liberation(struct_processus *s_etat_proc case PRC : { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -1155,7 +1192,7 @@ liberation(struct_processus *s_etat_proc } if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -1165,8 +1202,9 @@ liberation(struct_processus *s_etat_proc { pthread_mutex_destroy(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex)); + pthread_mutex_destroy(&((*(*((struct_processus_fils *) + (*s_objet).objet)).thread).mutex_nombre_references)); free((*((struct_processus_fils *) (*s_objet).objet)).thread); - } if (decrementation_atomique(s_objet) > 0) @@ -2201,20 +2239,9 @@ copie_objet(struct_processus *s_etat_pro case MTX : { - if (type != 'O') - { - incrementation_atomique(s_objet); - return(s_objet); - } - - if ((s_nouvel_objet = allocation(s_etat_processus, MTX)) == NULL) - { - return(NULL); - } - - (*((struct_mutex *) ((*s_nouvel_objet).objet))).mutex = - (*((struct_mutex *) ((*s_objet).objet))).mutex; - break; + // La duplication d'un mutex renvoie le même objet. + incrementation_atomique(s_objet); + return(s_objet); } case NOM : @@ -2256,19 +2283,24 @@ copie_objet(struct_processus *s_etat_pro return(s_objet); } + // Un objet de type NON est un objet encapsulé dans une + // structure de type struct_objet. Elle peut très bien contenir + // une donnée, mais c'est à l'utilisateur de la libérer + // explicitement avec un free(). + if ((s_nouvel_objet = allocation(s_etat_processus, NON)) == NULL) { return(NULL); } - (*s_nouvel_objet).objet = NULL; + (*s_nouvel_objet).objet = (*s_objet).objet; break; } case PRC : { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { return(NULL); } @@ -2277,7 +2309,7 @@ copie_objet(struct_processus *s_etat_pro .nombre_references++; if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { return(NULL); } @@ -2295,7 +2327,6 @@ copie_objet(struct_processus *s_etat_pro (*((struct_processus_fils *) (*s_nouvel_objet).objet)) = (*((struct_processus_fils *) (*s_objet).objet)); - break; } @@ -2470,6 +2501,8 @@ copie_objet(struct_processus *s_etat_pro return(NULL); } + (*((struct_semaphore *) (*s_nouvel_objet).objet)).semaphore = + (*((struct_semaphore *) (*s_objet).objet)).semaphore; strcpy((*((struct_semaphore *) (*s_nouvel_objet).objet)).nom, (*((struct_semaphore *) (*s_objet).objet)).nom); break; @@ -2787,18 +2820,18 @@ copie_etat_processus(struct_processus *s * n'ont aucune raison de changer. */ -# ifndef SEMAPHORES_NOMMES - sem_init(&((*s_nouvel_etat_processus).semaphore_fork), 0, 0); -# else - if (((*s_nouvel_etat_processus).semaphore_fork = sem_init2(0, sem_fork)) - == SEM_FAILED) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } -# endif + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); + (*s_nouvel_etat_processus).sections_critiques = 0; + + // Les sémaphores sont initialisés dans le nouveau thread. Il + // s'agit d'une limitation de l'implantation de l'émulation + // de sem_init(). + + initialisation_contexte_cas(s_etat_processus); (*s_nouvel_etat_processus).var_volatile_processus_pere = 0; + (*s_nouvel_etat_processus).var_volatile_processus_racine = 0; (*s_nouvel_etat_processus).fichiers_graphiques = NULL; (*s_nouvel_etat_processus).entree_standard = NULL; (*s_nouvel_etat_processus).s_marques = NULL; @@ -2842,10 +2875,17 @@ copie_etat_processus(struct_processus *s if ((*s_nouvel_etat_processus).generateur_aleatoire != NULL) { - (*s_nouvel_etat_processus).generateur_aleatoire = NULL; - } + if (((*s_nouvel_etat_processus).generateur_aleatoire = + gsl_rng_clone((*s_etat_processus).generateur_aleatoire)) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(NULL); + } - (*s_nouvel_etat_processus).type_generateur_aleatoire = NULL; + gsl_rng_set((*s_nouvel_etat_processus).generateur_aleatoire, + gsl_rng_get((*s_etat_processus).generateur_aleatoire)); + } // Copie de la localisation @@ -3072,80 +3112,19 @@ copie_etat_processus(struct_processus *s * Copie de la table des variables */ - if (((*s_nouvel_etat_processus).s_liste_variables = - malloc((*s_etat_processus).nombre_variables_allouees * - sizeof(struct_variable))) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } + copie_arbre_variables(s_etat_processus, s_nouvel_etat_processus); - for(i = 0; i < (*s_etat_processus).nombre_variables; i++) + if ((*s_nouvel_etat_processus).erreur_systeme != d_es) { - if (((*s_nouvel_etat_processus).s_liste_variables[i].nom = - malloc((strlen((*s_etat_processus).s_liste_variables[i].nom) - + 1) * sizeof(unsigned char))) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - - strcpy((*s_nouvel_etat_processus).s_liste_variables[i].nom, - (*s_etat_processus).s_liste_variables[i].nom); - - (*s_nouvel_etat_processus).s_liste_variables[i].origine = - (*s_etat_processus).s_liste_variables[i].origine; - (*s_nouvel_etat_processus).s_liste_variables[i].niveau = - (*s_etat_processus).s_liste_variables[i].niveau; - (*s_nouvel_etat_processus).s_liste_variables[i].variable_statique = - (*s_etat_processus).s_liste_variables[i].variable_statique; - (*s_nouvel_etat_processus).s_liste_variables[i].variable_partagee = - (*s_etat_processus).s_liste_variables[i].variable_partagee; - (*s_nouvel_etat_processus).s_liste_variables[i].variable_verrouillee = - (*s_etat_processus).s_liste_variables[i].variable_verrouillee; - - // Les définitions sont partagées entre tous les threads. - - if ((*s_etat_processus).s_liste_variables[i].niveau == 0) - { - (*s_nouvel_etat_processus).s_liste_variables[i].objet = - (*s_etat_processus).s_liste_variables[i].objet; - } - else - { - if (((*s_nouvel_etat_processus).s_liste_variables[i].objet = - copie_objet(s_etat_processus, - (*s_etat_processus).s_liste_variables[i] - .objet, 'P')) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - } + return(NULL); } /* * Copie de la table des variables statiques */ +#warning A FAIRE + /* if (((*s_nouvel_etat_processus).s_liste_variables_statiques = malloc((*s_etat_processus).nombre_variables_statiques_allouees * sizeof(struct_variable_statique))) == NULL) @@ -3201,6 +3180,7 @@ copie_etat_processus(struct_processus *s return(NULL); } } + */ /* * Copie de la pile opérationnelle @@ -3309,6 +3289,9 @@ copie_etat_processus(struct_processus *s * Copie des différents contextes */ + (*s_nouvel_etat_processus).pointeur_signal_lecture = d_faux; + (*s_nouvel_etat_processus).pointeur_signal_ecriture = d_faux; + (*s_nouvel_etat_processus).l_base_pile_contextes = NULL; l_element_lecture = (*s_etat_processus).l_base_pile_contextes; @@ -3975,6 +3958,9 @@ debug_fork() if (pid == 0) { + liberation_queue_signaux(s_etat_processus); + creation_queue_signaux(s_etat_processus); + pthread_mutex_destroy(&mutex_allocation); debug_memoire_initialisation(); }