--- rpl/src/gestion_objets.c 2010/05/22 21:47:07 1.19 +++ rpl/src/gestion_objets.c 2011/05/09 13:52:11 1.45.2.3 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.15 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.0.24 + Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -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; @@ -266,7 +266,7 @@ liberation_maillon(struct_processus *s_e ================================================================================ Routine d'allocation d'une structure *s_objet ================================================================================ - Entrées : structure sur l'état du processus et objet à afficher + Entrées : structure sur l'état du processus et objet à allouer -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- @@ -279,8 +279,20 @@ allocation(struct_processus *s_etat_proc { struct_objet *s_objet; + if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + if ((*s_etat_processus).pile_objets == NULL) { + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + // Il n'existe aucune structure struct_objet disponible dans le cache. if ((s_objet = malloc(sizeof(struct_objet))) == NULL) @@ -299,6 +311,12 @@ allocation(struct_processus *s_etat_proc (*s_etat_processus).taille_pile_objets--; (*s_objet).nombre_occurrences = 1; + + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } } (*s_objet).type = type; @@ -740,6 +758,9 @@ liberation(struct_processus *s_etat_proc { logical1 drapeau; + sigset_t oldset; + sigset_t set; + struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_suivant; @@ -1104,15 +1125,20 @@ liberation(struct_processus *s_etat_proc return; } - free(s_objet); break; } case PRC : { + sigfillset(&set); + pthread_sigmask(SIG_BLOCK, &set, &oldset); + if (pthread_mutex_lock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + (*s_etat_processus).erreur_systeme = d_es_processus; return; } @@ -1121,7 +1147,8 @@ liberation(struct_processus *s_etat_proc .nombre_references--; BUG((*(*((struct_processus_fils *) (*s_objet).objet)).thread) - .nombre_references < 0, printf("(*(*((struct_processus_fils" + .nombre_references < 0, uprintf( + "(*(*((struct_processus_fils" " *) (*s_objet).objet)).thread).nombre_references = %d\n", (int) (*(*((struct_processus_fils *) (*s_objet).objet)) .thread).nombre_references)); @@ -1137,21 +1164,32 @@ 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) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + (*s_etat_processus).erreur_systeme = d_es_processus; return; } + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + if (drapeau == d_vrai) { 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) { + BUG(drapeau == d_vrai, uprintf("(*(*((struct_processus_fils" + " *) (*s_objet).objet)).thread).nombre_references " + "= 0 with nombre_occurrences > 0\n")); return; } @@ -1416,30 +1454,36 @@ liberation(struct_processus *s_etat_proc return; } - if (s_etat_processus != NULL) + if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0) { - if ((*s_etat_processus).taille_pile_objets < TAILLE_CACHE) - { - (*s_objet).objet = (*s_etat_processus).pile_objets; - (*s_etat_processus).pile_objets = s_objet; - (*s_etat_processus).taille_pile_objets++; - } - else - { - if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } - free(s_objet); - } + if ((*s_etat_processus).taille_pile_objets < TAILLE_CACHE) + { + (*s_objet).objet = (*s_etat_processus).pile_objets; + (*s_etat_processus).pile_objets = s_objet; + (*s_etat_processus).taille_pile_objets++; } else { + if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0) + { + pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)); + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + free(s_objet); } + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + return; } @@ -1469,6 +1513,9 @@ struct_objet * copie_objet(struct_processus *s_etat_processus, struct_objet *s_objet, unsigned char type) { + sigset_t oldset; + sigset_t set; + struct_liste_chainee *l_element_base; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_ecriture; @@ -2239,9 +2286,15 @@ copie_objet(struct_processus *s_etat_pro case PRC : { + sigfillset(&set); + pthread_sigmask(SIG_BLOCK, &set, &oldset); + if (pthread_mutex_lock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + return(NULL); } @@ -2249,11 +2302,17 @@ 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) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + return(NULL); } + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + if (type != 'O') { incrementation_atomique(s_objet); @@ -2770,6 +2829,7 @@ copie_etat_processus(struct_processus *s # endif (*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; @@ -2800,6 +2860,8 @@ copie_etat_processus(struct_processus *s (*s_nouvel_etat_processus).nombre_interruptions_non_affectees = 0; (*s_nouvel_etat_processus).at_exit = NULL; + (*s_nouvel_etat_processus).at_poke = NULL; + (*s_nouvel_etat_processus).traitement_at_poke = 'N'; for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) { @@ -2811,10 +2873,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 @@ -3536,6 +3605,12 @@ copie_etat_processus(struct_processus *s pthread_mutex_init(&((*s_nouvel_etat_processus).mutex), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&((*s_nouvel_etat_processus).mutex_allocation), + &attributs_mutex); + pthread_mutexattr_destroy(&attributs_mutex); + if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -3565,20 +3640,24 @@ copie_etat_processus(struct_processus *s #undef malloc #undef realloc #undef free +#undef fork #ifdef return # undef return #endif -#undef fprintf - #ifdef __BACKTRACE +#define PROFONDEUR_PILE 64 #define return(a) { if (a == NULL) \ - { BACKTRACE(20); fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \ + { BACKTRACE(PROFONDEUR_PILE); \ + fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \ return(a); } while(0) -#define PROFONDEUR_PILE 64 #endif +#undef fprintf +#define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b)) +#undef CORE_DUMP + typedef struct memoire { void *pointeur; @@ -3596,10 +3675,20 @@ typedef struct memoire static struct_memoire *debug = NULL; static unsigned long long ordre = 0; -static pthread_mutex_t mutex_allocation = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mutex_allocation; -#define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b)) -#undef CORE_DUMP +void +debug_memoire_initialisation() +{ + pthread_mutexattr_t attributs_mutex; + + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex_allocation, &attributs_mutex); + pthread_mutexattr_destroy(&attributs_mutex); + + return; +} void * debug_memoire_ajout(size_t taille, const unsigned char *fonction, @@ -3607,6 +3696,8 @@ debug_memoire_ajout(size_t taille, const { struct_memoire *ancienne_base; + void *pointeur; + pthread_mutex_lock(&mutex_allocation); ancienne_base = debug; @@ -3628,6 +3719,8 @@ debug_memoire_ajout(size_t taille, const (*debug).taille = taille; (*debug).ordre = ordre; + pointeur = (*debug).pointeur; + # ifdef __BACKTRACE (*debug).profondeur = backtrace((*debug).pile, PROFONDEUR_PILE); # endif @@ -3649,10 +3742,12 @@ debug_memoire_ajout(size_t taille, const strcpy((*debug).fonction, fonction); strcpy((*debug).argument, argument); + memset((*debug).pointeur, 0, (*debug).taille); + pthread_mutex_unlock(&mutex_allocation); ordre++; - return((*debug).pointeur); + return(pointeur); } void * @@ -3666,9 +3761,11 @@ debug_memoire_modification(void *pointeu { if (taille == 0) { - // Revient à free() + // Revient à free(). Il n'y a pas de parenthèses car on ne veut + // pas utiliser la macro return(). + debug_memoire_retrait(pointeur); - return(NULL); + return NULL ; } else { @@ -3691,41 +3788,50 @@ debug_memoire_modification(void *pointeu if (element_courant == NULL) { pthread_mutex_unlock(&mutex_allocation); - return(NULL); - } - if (((*element_courant).pointeur = realloc(pointeur, taille)) - == NULL) - { - pthread_mutex_unlock(&mutex_allocation); - return(NULL); + uprintf("[%d-%llu] ILLEGAL POINTER (realloc)\n", + getpid(), (unsigned long long) pthread_self()); +# ifdef __BACKTRACE + BACKTRACE(PROFONDEUR_PILE); +# endif + + return(realloc(pointeur, taille)); } + else + { + if (((*element_courant).pointeur = realloc(pointeur, taille)) + == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } - (*element_courant).ligne = ligne; - (*element_courant).taille = taille; - free((*element_courant).fonction); - free((*element_courant).argument); + (*element_courant).ligne = ligne; + (*element_courant).taille = taille; + free((*element_courant).fonction); + free((*element_courant).argument); - if (((*element_courant).fonction = malloc((strlen(fonction) + 1) * - sizeof(unsigned char))) == NULL) - { - pthread_mutex_unlock(&mutex_allocation); - return(NULL); - } + if (((*element_courant).fonction = malloc((strlen(fonction) + + 1) * sizeof(unsigned char))) == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } - if (((*element_courant).argument = malloc((strlen(argument) + 1) * - sizeof(unsigned char))) == NULL) - { - pthread_mutex_unlock(&mutex_allocation); - return(NULL); - } + if (((*element_courant).argument = malloc((strlen(argument) + + 1) * sizeof(unsigned char))) == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } - strcpy((*element_courant).fonction, fonction); - strcpy((*element_courant).argument, argument); + strcpy((*element_courant).fonction, fonction); + strcpy((*element_courant).argument, argument); - pthread_mutex_unlock(&mutex_allocation); + pthread_mutex_unlock(&mutex_allocation); - return((*element_courant).pointeur); + return((*element_courant).pointeur); + } } } else @@ -3760,6 +3866,11 @@ debug_memoire_retrait(void *pointeur) (*element_precedent).suivant = (*element_courant).suivant; } + if (pointeur != NULL) + { + memset(pointeur, 0, (*element_courant).taille); + } + free((*element_courant).fonction); free((*element_courant).argument); free(element_courant); @@ -3773,8 +3884,16 @@ debug_memoire_retrait(void *pointeur) pthread_mutex_unlock(&mutex_allocation); - free(pointeur); + if (element_courant == NULL) + { + uprintf("[%d-%llu] ILLEGAL POINTER (free)\n", + getpid(), (unsigned long long) pthread_self()); +# ifdef __BACKTRACE + BACKTRACE(PROFONDEUR_PILE); +# endif + } + free(pointeur); return; } @@ -3876,6 +3995,7 @@ debug_memoire_verification() } pthread_mutex_unlock(&mutex_allocation); + pthread_mutex_destroy(&mutex_allocation); fprintf(stderr, "[%d-%llu] END OF LIST\n", getpid(), (unsigned long long) pthread_self()); @@ -3883,16 +4003,41 @@ debug_memoire_verification() return; } -void -debug_memoire_reinitialisation() +pid_t +debug_fork() { - ordre = 0; - debug = NULL; + pid_t pid; - pthread_mutex_trylock(&mutex_allocation); - pthread_mutex_unlock(&mutex_allocation); + pthread_mutex_lock(&mutex_allocation); + pid = fork(); - return; +# ifdef OS2 + if (pid == 0) + { + sem_init(&semaphore_liste_threads, 0, 1); + sem_init(&semaphore_gestionnaires_signaux, 0, 0); + sem_init(&semaphore_gestionnaires_signaux_atomique, 0, 1); + sem_init(&((*s_etat_processus).semaphore_fork), 0, 0); + } +# endif + + if (pid == 0) + { +# ifdef _BROKEN_SIGINFO + liberation_fifos_signaux(s_etat_processus); + creation_fifos_signaux(s_etat_processus); +# endif + + pthread_mutex_destroy(&mutex_allocation); + debug_memoire_initialisation(); + } + else + { + pthread_mutex_unlock(&mutex_allocation); + } + + // Pas de parenthèses pour ne pas remplacer return par sa macro. + return pid; } void