/* ================================================================================ RPL/2 (R) version 4.1.32 Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Routines de gestion du nombre d'occurrences comme grandeur atomique ================================================================================ entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- sorties : chaine de caractères -------------------------------------------------------------------------------- effets de bord : néant ================================================================================ */ static inline void incrementation_atomique(struct_objet *s_objet) { // Le mutex est sur l'objet. (*s_objet).nombre_occurrences++; BUG((*s_objet).nombre_occurrences <= 0, uprintf("Capacity exceeded %ld\n", (*s_objet).nombre_occurrences)); return; } static inline long decrementation_atomique(struct_objet *s_objet) { // Le mutex est sur l'objet. (*s_objet).nombre_occurrences--; return((*s_objet).nombre_occurrences); } void initialisation_objet(struct_objet *s_objet) { pthread_mutexattr_t attributs_mutex; pthread_mutexattr_init(&attributs_mutex); pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&((*s_objet).mutex), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); (*s_objet).nombre_occurrences = 1; return; } /* ================================================================================ Routines d'initialisation et de purge de l'allocateur ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void initialisation_allocateur(struct_processus *s_etat_processus) { (*s_etat_processus).estimation_taille_pile_tampon = 0; (*s_etat_processus).taille_pile_tampon = 0; (*s_etat_processus).pile_tampon = NULL; (*s_etat_processus).estimation_taille_pile_systeme_tampon = 0; (*s_etat_processus).taille_pile_systeme_tampon = 0; (*s_etat_processus).pile_systeme_tampon = NULL; (*s_etat_processus).taille_pile_objets = 0; (*s_etat_processus).pile_objets = NULL; (*s_etat_processus).pointeur_adr = 0; (*s_etat_processus).pointeur_bin = 0; (*s_etat_processus).pointeur_cpl = 0; (*s_etat_processus).pointeur_fct = 0; (*s_etat_processus).pointeur_int = 0; (*s_etat_processus).pointeur_mat = 0; (*s_etat_processus).pointeur_nom = 0; (*s_etat_processus).pointeur_rec = 0; (*s_etat_processus).pointeur_rel = 0; (*s_etat_processus).pointeur_tab = 0; (*s_etat_processus).pointeur_vec = 0; (*s_etat_processus).pointeur_maillons = 0; (*s_etat_processus).pointeur_variables_noeud = 0; (*s_etat_processus).pointeur_variables_partagees_noeud = 0; (*s_etat_processus).pointeur_variables_feuille = 0; (*s_etat_processus).pointeur_variables_variable = 0; (*s_etat_processus).pointeur_variables_tableau_noeuds = 0; (*s_etat_processus).pointeur_variables_tableau_noeuds_partages = 0; return; } void liberation_allocateur(struct_processus *s_etat_processus) { int i; for(i = 0; i < (*s_etat_processus).pointeur_adr; free((*s_etat_processus).objets_adr[i++])); for(i = 0; i < (*s_etat_processus).pointeur_bin; free((*s_etat_processus).objets_bin[i++])); for(i = 0; i < (*s_etat_processus).pointeur_cpl; free((*s_etat_processus).objets_cpl[i++])); for(i = 0; i < (*s_etat_processus).pointeur_fct; free((*s_etat_processus).objets_fct[i++])); for(i = 0; i < (*s_etat_processus).pointeur_int; free((*s_etat_processus).objets_int[i++])); for(i = 0; i < (*s_etat_processus).pointeur_mat; free((*s_etat_processus).objets_mat[i++])); for(i = 0; i < (*s_etat_processus).pointeur_nom; free((*s_etat_processus).objets_nom[i++])); for(i = 0; i < (*s_etat_processus).pointeur_rec; free((*s_etat_processus).objets_rec[i++])); for(i = 0; i < (*s_etat_processus).pointeur_rel; free((*s_etat_processus).objets_rel[i++])); for(i = 0; i < (*s_etat_processus).pointeur_tab; free((*s_etat_processus).objets_tab[i++])); for(i = 0; i < (*s_etat_processus).pointeur_vec; free((*s_etat_processus).objets_vec[i++])); 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_partagees_noeud; free((*s_etat_processus).variables_partagees_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++])); for(i = 0; i < (*s_etat_processus) .pointeur_variables_tableau_noeuds_partages; free((*s_etat_processus).variables_tableau_noeuds_partages[i++])); { struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_suivant; l_element_courant = (*s_etat_processus).pile_tampon; while(l_element_courant != NULL) { l_element_suivant = (*l_element_courant).suivant; liberation(s_etat_processus, (*l_element_courant).donnee); free(l_element_courant); l_element_courant = l_element_suivant; } } { struct_liste_pile_systeme *l_element_courant; struct_liste_pile_systeme *l_element_suivant; l_element_courant = (*s_etat_processus).pile_systeme_tampon; while(l_element_courant != NULL) { l_element_suivant = (*l_element_courant).suivant; free(l_element_courant); l_element_courant = l_element_suivant; } } { struct_objet *l_element_courant; struct_objet *l_element_suivant; l_element_courant = (*s_etat_processus).pile_objets; while(l_element_courant != NULL) { l_element_suivant = (*l_element_courant).objet; if (pthread_mutex_destroy(&((*l_element_courant).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; BUG(1, printf("Mutex error\n")); return; } free(l_element_courant); l_element_courant = l_element_suivant; } } return; } /* ================================================================================ Routine d'allocation d'un maillon d'un objet (liste, expression...) ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void * allocation_maillon(struct_processus *s_etat_processus) { struct_liste_chainee *s_maillon; if ((*s_etat_processus).pointeur_maillons > 0) { s_maillon = (*s_etat_processus).maillons [--(*s_etat_processus).pointeur_maillons]; } else { if ((s_maillon = malloc(sizeof(struct_liste_chainee))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } } return(s_maillon); } /* ================================================================================ Routine de libération d'un maillon d'un objet (liste, expression...) ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void liberation_maillon(struct_processus *s_etat_processus, struct_liste_chainee *maillon) { if ((*s_etat_processus).pointeur_maillons < TAILLE_CACHE) { (*s_etat_processus).maillons [(*s_etat_processus).pointeur_maillons++] = maillon; } else { free(maillon); } return; } /* ================================================================================ Routine d'allocation d'une structure *s_objet ================================================================================ Entrées : structure sur l'état du processus et objet à allouer -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ struct_objet * allocation(struct_processus *s_etat_processus, enum t_type type) { 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) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } initialisation_objet(s_objet); } else { // Récupération d'une structure dans le cache. s_objet = (*s_etat_processus).pile_objets; (*s_etat_processus).pile_objets = (*s_objet).objet; (*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; (*s_objet).extension_type = 0; (*s_objet).descripteur_bibliotheque = NULL; switch(type) { case ADR : { if ((*s_etat_processus).pointeur_adr > 0) { (*s_objet).objet = (*s_etat_processus).objets_adr [--(*s_etat_processus).pointeur_adr]; } else { if (((*s_objet).objet = malloc(sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case ALG : { (*s_objet).objet = NULL; break; } case BIN : { if ((*s_etat_processus).pointeur_bin > 0) { (*s_objet).objet = (*s_etat_processus).objets_bin [--(*s_etat_processus).pointeur_bin]; } else { if (((*s_objet).objet = malloc(sizeof(logical8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case CHN : { (*s_objet).objet = NULL; break; } case CPL : { if ((*s_etat_processus).pointeur_cpl > 0) { (*s_objet).objet = (*s_etat_processus).objets_cpl [--(*s_etat_processus).pointeur_cpl]; } else { if (((*s_objet).objet = malloc(sizeof(struct_complexe16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case FCH : { if (((*s_objet).objet = malloc(sizeof(struct_fichier))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } break; } case EXT : { // Aucune allocation break; } case FCT : { if ((*s_etat_processus).pointeur_fct > 0) { (*s_objet).objet = (*s_etat_processus).objets_fct [--(*s_etat_processus).pointeur_fct]; } else { if (((*s_objet).objet = malloc(sizeof(struct_fonction))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_fonction *) (*s_objet).objet)).fonction = NULL; (*((struct_fonction *) (*s_objet).objet)).prediction_saut = NULL; (*((struct_fonction *) (*s_objet).objet)).prediction_execution = d_faux; break; } case INT : { if ((*s_etat_processus).pointeur_int > 0) { (*s_objet).objet = (*s_etat_processus).objets_int [--(*s_etat_processus).pointeur_int]; } else { if (((*s_objet).objet = malloc(sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case LST : { (*s_objet).objet = NULL; break; } case MCX : { if ((*s_etat_processus).pointeur_mat > 0) { (*s_objet).objet = (*s_etat_processus).objets_mat [--(*s_etat_processus).pointeur_mat]; } else { if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_matrice *) (*s_objet).objet)).type = 'C'; (*((struct_matrice *) (*s_objet).objet)).nombre_lignes = 0; (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes = 0; (*((struct_matrice *) (*s_objet).objet)).tableau = NULL; break; } case MIN : { if ((*s_etat_processus).pointeur_mat > 0) { (*s_objet).objet = (*s_etat_processus).objets_mat [--(*s_etat_processus).pointeur_mat]; } else { if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_matrice *) (*s_objet).objet)).type = 'I'; (*((struct_matrice *) (*s_objet).objet)).nombre_lignes = 0; (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes = 0; (*((struct_matrice *) (*s_objet).objet)).tableau = NULL; break; } case MRL : { if ((*s_etat_processus).pointeur_mat > 0) { (*s_objet).objet = (*s_etat_processus).objets_mat [--(*s_etat_processus).pointeur_mat]; } else { if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_matrice *) (*s_objet).objet)).type = 'R'; (*((struct_matrice *) (*s_objet).objet)).nombre_lignes = 0; (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes = 0; (*((struct_matrice *) (*s_objet).objet)).tableau = NULL; break; } case MTX : { if (((*s_objet).objet = malloc(sizeof(struct_mutex))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self(); break; } case NOM : { if ((*s_etat_processus).pointeur_nom > 0) { (*s_objet).objet = (*s_etat_processus).objets_nom [--(*s_etat_processus).pointeur_nom]; } else { if (((*s_objet).objet = malloc(sizeof(struct_nom))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case NON : { (*s_objet).objet = NULL; break; } case PRC : { if (((*s_objet).objet = malloc(sizeof(struct_processus_fils))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } break; } case REC : { if ((*s_etat_processus).pointeur_rec > 0) { (*s_objet).objet = (*s_etat_processus).objets_rec [--(*s_etat_processus).pointeur_rec]; } else { if (((*s_objet).objet = malloc(sizeof(struct_record))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case REL : { if ((*s_etat_processus).pointeur_rel > 0) { (*s_objet).objet = (*s_etat_processus).objets_rel [--(*s_etat_processus).pointeur_rel]; } else { if (((*s_objet).objet = malloc(sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } break; } case RPN : { (*s_objet).objet = NULL; break; } case SCK : { if (((*s_objet).objet = malloc(sizeof(struct_socket))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } break; } case SLB : { if (((*s_objet).objet = malloc(sizeof(struct_bibliotheque))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } break; } case SPH : { if (((*s_objet).objet = malloc(sizeof(struct_semaphore))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } break; } case SQL : { if (((*s_objet).objet = malloc(sizeof(struct_connecteur_sql))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } break; } case TBL : { if ((*s_etat_processus).pointeur_tab > 0) { (*s_objet).objet = (*s_etat_processus).objets_tab [--(*s_etat_processus).pointeur_tab]; } else { if (((*s_objet).objet = malloc(sizeof(struct_tableau))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_tableau *) (*s_objet).objet)).nombre_elements = 0; (*((struct_tableau *) (*s_objet).objet)).elements = NULL; break; } case VCX : { if ((*s_etat_processus).pointeur_vec > 0) { (*s_objet).objet = (*s_etat_processus).objets_vec [--(*s_etat_processus).pointeur_vec]; } else { if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_vecteur *) (*s_objet).objet)).type = 'C'; (*((struct_vecteur *) (*s_objet).objet)).taille = 0; (*((struct_vecteur *) (*s_objet).objet)).tableau = NULL; break; } case VIN : { if ((*s_etat_processus).pointeur_vec > 0) { (*s_objet).objet = (*s_etat_processus).objets_vec [--(*s_etat_processus).pointeur_vec]; } else { if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_vecteur *) (*s_objet).objet)).type = 'I'; (*((struct_vecteur *) (*s_objet).objet)).taille = 0; (*((struct_vecteur *) (*s_objet).objet)).tableau = NULL; break; } case VRL : { if ((*s_etat_processus).pointeur_vec > 0) { (*s_objet).objet = (*s_etat_processus).objets_vec [--(*s_etat_processus).pointeur_vec]; } else { if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(s_objet); return(NULL); } } (*((struct_vecteur *) (*s_objet).objet)).type = 'R'; (*((struct_vecteur *) (*s_objet).objet)).taille = 0; (*((struct_vecteur *) (*s_objet).objet)).tableau = NULL; break; } default : { free(s_objet); BUG(1, printf("Allocation failure (type %d)\n", type)); return(NULL); } } return(s_objet); } /* ================================================================================ Routine de libération d'une structure *s_objet ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void liberation(struct_processus *s_etat_processus, struct_objet *s_objet) { logical1 drapeau; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_suivant; integer8 i; integer8 (*__type_drop)(struct_processus *, void **); if (s_objet == NULL) { return; } if (pthread_mutex_lock(&((*s_objet).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } #define return \ if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0) \ { (*s_etat_processus).erreur_systeme = d_es_processus; return; } \ return BUG((*s_objet).nombre_occurrences <= 0, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*s_objet).nombre_occurrences=%ld\n", (*s_objet).nombre_occurrences)); switch((*s_objet).type) { case ADR : { if (decrementation_atomique(s_objet) > 0) { return; } if ((*s_etat_processus).pointeur_adr < TAILLE_CACHE) { (*s_etat_processus).objets_adr [(*s_etat_processus).pointeur_adr++] = (*s_objet).objet; } else { free((*s_objet).objet); } break; } case ALG : { l_element_courant = (struct_liste_chainee *) ((*s_objet).objet); if (decrementation_atomique(s_objet) > 0) { // Il reste un pointeur sur l'objet. while(l_element_courant != NULL) { BUG((*(*l_element_courant).donnee).nombre_occurrences <= 1, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*(*l_element_courant).donnee)" ".nombre_occurrences=%ld\n", (*(*l_element_courant).donnee).nombre_occurrences)); liberation(s_etat_processus, (*l_element_courant).donnee); l_element_courant = (*l_element_courant).suivant; } return; } else { // Il ne reste plus aucun pointeur sur l'objet. while(l_element_courant != NULL) { l_element_suivant = (*l_element_courant).suivant; liberation(s_etat_processus, (*l_element_courant).donnee); liberation_maillon(s_etat_processus, l_element_courant); l_element_courant = l_element_suivant; } } break; } case BIN : { if (decrementation_atomique(s_objet) > 0) { return; } if ((*s_etat_processus).pointeur_bin < TAILLE_CACHE) { (*s_etat_processus).objets_bin [(*s_etat_processus).pointeur_bin++] = (*s_objet).objet; } else { free((logical8 *) ((*s_objet).objet)); } break; } case CHN : { if (decrementation_atomique(s_objet) > 0) { return; } free((unsigned char *) (*s_objet).objet); break; } case CPL : { if (decrementation_atomique(s_objet) > 0) { return; } if ((*s_etat_processus).pointeur_cpl < TAILLE_CACHE) { (*s_etat_processus).objets_cpl [(*s_etat_processus).pointeur_cpl++] = (*s_objet).objet; } else { free((struct_complexe16 *) ((*s_objet).objet)); } break; } case FCH : { if (decrementation_atomique(s_objet) > 0) { BUG((*(*((struct_fichier *) (*s_objet).objet)).format) .nombre_occurrences <= 1, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*(*((struct_fichier *) (*s_objet).objet))" ".format).nombre_occurrences=%ld\n", (*(*((struct_fichier *) (*s_objet).objet)).format) .nombre_occurrences)); liberation(s_etat_processus, (*((struct_fichier *) (*s_objet).objet)).format); return; } liberation(s_etat_processus, (*((struct_fichier *) (*s_objet).objet)).format); free((unsigned char *) (*((struct_fichier *) (*s_objet).objet)).nom); free((struct_fichier *) ((*s_objet).objet)); break; } case FCT : { if (decrementation_atomique(s_objet) > 0) { return; } free((unsigned char *) (*((struct_fonction *) (*s_objet).objet)).nom_fonction); if ((*s_etat_processus).pointeur_fct < TAILLE_CACHE) { (*s_etat_processus).objets_fct [(*s_etat_processus).pointeur_fct++] = (*s_objet).objet; } else { free((struct_fonction *) (*s_objet).objet); } break; } case INT : { if (decrementation_atomique(s_objet) > 0) { return; } if ((*s_etat_processus).pointeur_int < TAILLE_CACHE) { (*s_etat_processus).objets_int [(*s_etat_processus).pointeur_int++] = (*s_objet).objet; } else { free((integer8 *) ((*s_objet).objet)); } break; } case LST : { l_element_courant = (struct_liste_chainee *) ((*s_objet).objet); if (decrementation_atomique(s_objet) > 0) { // Il reste un pointeur sur l'objet. while(l_element_courant != NULL) { BUG((*(*l_element_courant).donnee).nombre_occurrences <= 1, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*(*l_element_courant).donnee)" ".nombre_occurrences=%ld\n", (*(*l_element_courant).donnee).nombre_occurrences)); liberation(s_etat_processus, (*l_element_courant).donnee); l_element_courant = (*l_element_courant).suivant; } return; } else { // Il ne reste plus aucun pointeur sur l'objet. while(l_element_courant != NULL) { l_element_suivant = (*l_element_courant).suivant; liberation(s_etat_processus, (*l_element_courant).donnee); liberation_maillon(s_etat_processus, l_element_courant); l_element_courant = l_element_suivant; } } break; } case MIN : { if (decrementation_atomique(s_objet) > 0) { return; } for(i = 0; i < (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; i++) { free(((integer8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i]); } free((integer8 **) (*((struct_matrice *) (*s_objet).objet)).tableau); if ((*s_etat_processus).pointeur_mat < TAILLE_CACHE) { (*s_etat_processus).objets_mat [(*s_etat_processus).pointeur_mat++] = (*s_objet).objet; } else { free((struct_matrice *) (*s_objet).objet); } break; } case MCX : { if (decrementation_atomique(s_objet) > 0) { return; } for(i = 0; i < (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; i++) { free(((struct_complexe16 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i]); } free((struct_complexe16 **) (*((struct_matrice *) (*s_objet).objet)).tableau); if ((*s_etat_processus).pointeur_mat < TAILLE_CACHE) { (*s_etat_processus).objets_mat [(*s_etat_processus).pointeur_mat++] = (*s_objet).objet; } else { free((struct_matrice *) (*s_objet).objet); } break; } case MRL : { if (decrementation_atomique(s_objet) > 0) { return; } for(i = 0; i < (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; i++) { free(((real8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i]); } free((real8 **) (*((struct_matrice *) (*s_objet).objet)).tableau); if ((*s_etat_processus).pointeur_mat < TAILLE_CACHE) { (*s_etat_processus).objets_mat [(*s_etat_processus).pointeur_mat++] = (*s_objet).objet; } else { free((struct_matrice *) (*s_objet).objet); } break; } case MTX : { if (decrementation_atomique(s_objet) > 0) { 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; } case NOM : { if (decrementation_atomique(s_objet) > 0) { return; } free((*((struct_nom *) (*s_objet).objet)).nom); if ((*s_etat_processus).pointeur_nom < TAILLE_CACHE) { (*s_etat_processus).objets_nom [(*s_etat_processus).pointeur_nom++] = (*s_objet).objet; } else { free((struct_nom *) (*s_objet).objet); } break; } case NON : { if (decrementation_atomique(s_objet) > 0) { return; } break; } case PRC : { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .nombre_references--; BUG((*(*((struct_processus_fils *) (*s_objet).objet)).thread) .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)); if ((*(*((struct_processus_fils *) (*s_objet).objet)).thread) .nombre_references == 0) { drapeau = d_vrai; } else { drapeau = d_faux; } if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } 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; } free((struct_processus_fils *) ((*s_objet).objet)); break; } case REC : { liberation(s_etat_processus, (*((struct_record *) (*s_objet).objet)).noms); liberation(s_etat_processus, (*((struct_record *) (*s_objet).objet)).donnees); if (decrementation_atomique(s_objet) > 0) { return; } if ((*s_etat_processus).pointeur_rec < TAILLE_CACHE) { (*s_etat_processus).objets_rec [(*s_etat_processus).pointeur_rec++] = (*s_objet).objet; } else { free((struct_record *) ((*s_objet).objet)); } break; } case REL : { if (decrementation_atomique(s_objet) > 0) { return; } if ((*s_etat_processus).pointeur_rel < TAILLE_CACHE) { (*s_etat_processus).objets_rel [(*s_etat_processus).pointeur_rel++] = (*s_objet).objet; } else { free((real8 *) ((*s_objet).objet)); } break; } case RPN : { l_element_courant = (struct_liste_chainee *) ((*s_objet).objet); if (decrementation_atomique(s_objet) > 0) { // Il reste un pointeur sur l'objet. while(l_element_courant != NULL) { BUG((*(*l_element_courant).donnee).nombre_occurrences <= 1, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*(*l_element_courant).donnee)" ".nombre_occurrences=%ld\n", (*(*l_element_courant).donnee).nombre_occurrences)); liberation(s_etat_processus, (*l_element_courant).donnee); l_element_courant = (*l_element_courant).suivant; } return; } else { // Il ne reste plus aucun pointeur sur l'objet. while(l_element_courant != NULL) { l_element_suivant = (*l_element_courant).suivant; liberation(s_etat_processus, (*l_element_courant).donnee); liberation_maillon(s_etat_processus, l_element_courant); l_element_courant = l_element_suivant; } } break; } case SCK : { if (decrementation_atomique(s_objet) > 0) { BUG((*(*((struct_socket *) (*s_objet).objet)).format) .nombre_occurrences <= 1, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*(*((struct_socket *) (*s_objet).objet))" ".format).nombre_occurrences=%ld\n", (*(*((struct_socket *) (*s_objet).objet)).format) .nombre_occurrences)); liberation(s_etat_processus, (*((struct_socket *) (*s_objet).objet)).format); return; } liberation(s_etat_processus, (*((struct_socket *) (*s_objet).objet)).format); free((unsigned char *) (*((struct_socket *) (*s_objet).objet)) .adresse); free((unsigned char *) (*((struct_socket *) (*s_objet).objet)) .adresse_distante); free((struct_socket *) ((*s_objet).objet)); break; } case SLB : { if (decrementation_atomique(s_objet) > 0) { return; } free((*((struct_bibliotheque *) (*s_objet).objet)).nom); free((struct_bibliotheque *) (*s_objet).objet); break; } case SPH : { if (decrementation_atomique(s_objet) > 0) { return; } free((*((struct_semaphore *) (*s_objet).objet)).nom); free((struct_bibliotheque *) (*s_objet).objet); break; } case SQL : { if (decrementation_atomique(s_objet) > 0) { return; } free((*((struct_connecteur_sql *) (*s_objet).objet)).type); free((*((struct_connecteur_sql *) (*s_objet).objet)).locale); free((struct_connecteur_sql *) (*s_objet).objet); break; } case TBL : { if (decrementation_atomique(s_objet) > 0) { for(i = 0; i < (*((struct_tableau *) (*s_objet).objet)) .nombre_elements; i++) { BUG((*((*((struct_tableau *) (*s_objet).objet)).elements[i])) .nombre_occurrences <= 1, pthread_mutex_unlock(&((*s_objet).mutex)), printf("(*((*((struct_tableau *) (*s_objet).objet))" ".element[%lld])).nombre_occurrences=%ld\n", i, (*((*((struct_tableau *) (*s_objet).objet)) .elements[i])).nombre_occurrences)); liberation(s_etat_processus, (*((struct_tableau *) (*s_objet).objet)).elements[i]); } return; } for(i = 0; i < (*((struct_tableau *) (*s_objet).objet)) .nombre_elements; i++) { liberation(s_etat_processus, (*((struct_tableau *) (*s_objet).objet)).elements[i]); } free((*((struct_tableau *) (*s_objet).objet)).elements); if ((*s_etat_processus).pointeur_tab < TAILLE_CACHE) { (*s_etat_processus).objets_tab [(*s_etat_processus).pointeur_tab++] = (*s_objet).objet; } else { free((struct_tableau *) (*s_objet).objet); } break; } case VIN : { if (decrementation_atomique(s_objet) > 0) { return; } free((integer8 *) (*((struct_vecteur *) (*s_objet).objet)).tableau); if ((*s_etat_processus).pointeur_vec < TAILLE_CACHE) { (*s_etat_processus).objets_vec [(*s_etat_processus).pointeur_vec++] = (*s_objet).objet; } else { free((struct_vecteur *) (*s_objet).objet); } break; } case VCX : { if (decrementation_atomique(s_objet) > 0) { return; } free((struct_complexe16 *) (*((struct_vecteur *) (*s_objet).objet)).tableau); if ((*s_etat_processus).pointeur_vec < TAILLE_CACHE) { (*s_etat_processus).objets_vec [(*s_etat_processus).pointeur_vec++] = (*s_objet).objet; } else { free((struct_vecteur *) (*s_objet).objet); } break; } case VRL : { if (decrementation_atomique(s_objet) > 0) { return; } free((real8 *) (*((struct_vecteur *) (*s_objet).objet)).tableau); if ((*s_etat_processus).pointeur_vec < TAILLE_CACHE) { (*s_etat_processus).objets_vec [(*s_etat_processus).pointeur_vec++] = (*s_objet).objet; } else { free((struct_vecteur *) (*s_objet).objet); } break; } case EXT: { if (decrementation_atomique(s_objet) > 0) { return; } // Appel de la fonction de liberation associée à l'objet // externe. Le descripteur de bibliothèque est directement // associé à la structure objet. l_element_courant = (*s_etat_processus).s_bibliotheques; while(l_element_courant != NULL) { if ((*((struct_bibliotheque *) (*l_element_courant).donnee)) .descripteur == (*s_objet).descripteur_bibliotheque) { if ((__type_drop = dlsym((*s_objet) .descripteur_bibliotheque, "__type_drop")) == NULL) { // La fonction de libération n'existe pas dans la // bibliothèque. (*s_etat_processus).erreur_execution = d_ex_type_externe_drop; } else { if (__type_drop(s_etat_processus, (void **) &s_objet) == 0) { (*s_etat_processus).erreur_execution = d_ex_type_externe_drop; } } break; } l_element_courant = (*l_element_courant).suivant; } if (l_element_courant == NULL) { (*s_etat_processus).erreur_execution = d_ex_type_externe_drop; } break; } default : { if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } BUG(1, printf("Free failure (type %d)\n", (*s_objet).type)); return; } } #undef return if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } 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; } /* ================================================================================ Routine de copie d'une structure *s_objet ================================================================================ Entrées : structure *s_objet à copier type : 'P' : renvoie le même objet en incrémentant le nombre d'occurrence de chaque objet élémentaire ; 'O' : crée un nouvel objet en copiant chaque objet élémentaire ; 'N' : crée un nouvel objet mais les objets élémentaires sont réutilisés (voir 'P'). Dans le cas d'un objet élémentaire, 'N' et 'P' sont identiques. 'Q' : 'P' si nombre_occurrences vaut 1, 'O' sinon. 'R' : 'P' si nombre_occurrences vaut 1, 'N' sinon. -------------------------------------------------------------------------------- Sorties : structure identique (tous les objets sont copiés) -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ struct_objet * copie_objet(struct_processus *s_etat_processus, struct_objet *s_objet, unsigned char type) { struct_liste_chainee *l_element_base; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_ecriture; struct_liste_chainee *l_element_courant_lecture; struct_liste_chainee *l_element_suivant_ecriture; struct_liste_chainee *l_element_suivant_lecture; struct_objet *s_nouvel_objet; struct_objet *s_objet_tampon; integer8 i; integer8 j; integer8 (*__type_dup)(struct_processus *, void **); if (pthread_mutex_lock(&((*s_objet).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } if (type == 'Q') { if ((*s_objet).nombre_occurrences == 1) { type = 'P'; } else { type = 'O'; } } else if (type == 'R') { if ((*s_objet).nombre_occurrences == 1) { type = 'P'; } else { type = 'N'; } } #define return(pointeur) \ if (pthread_mutex_unlock(&((*s_objet).mutex))) \ { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } \ return(pointeur) switch((*s_objet).type) { case ADR : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, ADR)) == NULL) { return(NULL); } (*((integer8 *) ((*s_nouvel_objet).objet))) = (*((integer8 *) ((*s_objet).objet))); break; } case ALG : { if (type != 'P') { if ((s_nouvel_objet = allocation(s_etat_processus, ALG)) == NULL) { return(NULL); } l_element_courant_lecture = (struct_liste_chainee *) ((*s_objet).objet); l_element_base = NULL; l_element_courant_ecriture = l_element_base; while(l_element_courant_lecture != NULL) { s_objet_tampon = copie_objet(s_etat_processus, (*l_element_courant_lecture).donnee, type); l_element_suivant_ecriture = (struct_liste_chainee *) malloc(sizeof(struct_liste_chainee)); if ((s_objet_tampon == NULL) || (l_element_suivant_ecriture == NULL)) { l_element_courant_lecture = (struct_liste_chainee *) ((*s_nouvel_objet).objet); while(l_element_courant_lecture != NULL) { l_element_suivant_lecture = (*l_element_courant_lecture).suivant; liberation(s_etat_processus, (*l_element_courant_lecture).donnee); free(l_element_courant_lecture); l_element_courant_lecture = l_element_suivant_lecture; } return(NULL); } if (l_element_courant_ecriture == NULL) { l_element_base = l_element_suivant_ecriture; } else { (*l_element_courant_ecriture).suivant = l_element_suivant_ecriture; } l_element_courant_ecriture = l_element_suivant_ecriture; (*l_element_courant_ecriture).donnee = s_objet_tampon; (*l_element_courant_ecriture).suivant = NULL; l_element_courant_lecture = (*l_element_courant_lecture).suivant; } (*s_nouvel_objet).objet = ((struct_liste_chainee *) l_element_base); } else // type == 'P' { incrementation_atomique(s_objet); l_element_courant = (*s_objet).objet; while(l_element_courant != NULL) { (*l_element_courant).donnee = copie_objet(s_etat_processus, (*l_element_courant).donnee, 'P'); l_element_courant = (*l_element_courant).suivant; } return(s_objet); } break; } case BIN : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, BIN)) == NULL) { return(NULL); } (*((logical8 *) ((*s_nouvel_objet).objet))) = (*((logical8 *) ((*s_objet).objet))); break; } case CHN : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, CHN)) == NULL) { return(NULL); } (*s_nouvel_objet).objet = ((unsigned char *) malloc((strlen((unsigned char *) ((*s_objet).objet)) + 1) * sizeof(unsigned char))); if ((*s_nouvel_objet).objet == NULL) { free(s_nouvel_objet); return(NULL); } strcpy((unsigned char *) ((*s_nouvel_objet).objet), (unsigned char *) ((*s_objet).objet)); break; } case CPL : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, CPL)) == NULL) { return(NULL); } (*((struct_complexe16 *) ((*s_nouvel_objet).objet))) = (*((struct_complexe16 *) ((*s_objet).objet))); break; } case RPN : { if (type != 'P') { if ((s_nouvel_objet = allocation(s_etat_processus, RPN)) == NULL) { return(NULL); } l_element_courant_lecture = (struct_liste_chainee *) ((*s_objet).objet); l_element_base = NULL; l_element_courant_ecriture = l_element_base; while(l_element_courant_lecture != NULL) { s_objet_tampon = copie_objet(s_etat_processus, (*l_element_courant_lecture).donnee, type); l_element_suivant_ecriture = (struct_liste_chainee *) malloc(sizeof(struct_liste_chainee)); if ((s_objet_tampon == NULL) || (l_element_suivant_ecriture == NULL)) { l_element_courant_lecture = (struct_liste_chainee *) ((*s_nouvel_objet).objet); while(l_element_courant_lecture != NULL) { l_element_suivant_lecture = (*l_element_courant_lecture).suivant; liberation(s_etat_processus, (*l_element_courant_lecture).donnee); free(l_element_courant_lecture); l_element_courant_lecture = l_element_suivant_lecture; } return(NULL); } if (l_element_courant_ecriture == NULL) { l_element_base = l_element_suivant_ecriture; } else { (*l_element_courant_ecriture).suivant = l_element_suivant_ecriture; } l_element_courant_ecriture = l_element_suivant_ecriture; (*l_element_courant_ecriture).donnee = s_objet_tampon; (*l_element_courant_ecriture).suivant = NULL; l_element_courant_lecture = (*l_element_courant_lecture).suivant; } (*s_nouvel_objet).objet = ((struct_liste_chainee *) l_element_base); } else // type == 'P' { incrementation_atomique(s_objet); l_element_courant = (*s_objet).objet; while(l_element_courant != NULL) { (*l_element_courant).donnee = copie_objet(s_etat_processus, (*l_element_courant).donnee, 'P'); l_element_courant = (*l_element_courant).suivant; } return(s_objet); } break; } case FCH : { if (type == 'P') { incrementation_atomique(s_objet); if (((*((struct_fichier *) ((*s_objet).objet))).format = copie_objet(s_etat_processus, (*((struct_fichier *) ((*s_objet).objet))).format, 'P')) == NULL) { return(NULL); } return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, FCH)) == NULL) { return(NULL); } (*((struct_fichier *) ((*s_nouvel_objet).objet))).descripteur = (*((struct_fichier *) ((*s_objet).objet))).descripteur; (*((struct_fichier *) ((*s_nouvel_objet).objet))).acces = (*((struct_fichier *) ((*s_objet).objet))).acces; (*((struct_fichier *) ((*s_nouvel_objet).objet))).binaire = (*((struct_fichier *) ((*s_objet).objet))).binaire; (*((struct_fichier *) ((*s_nouvel_objet).objet))).ouverture = (*((struct_fichier *) ((*s_objet).objet))).ouverture; (*((struct_fichier *) ((*s_nouvel_objet).objet))).protection = (*((struct_fichier *) ((*s_objet).objet))).protection; (*((struct_fichier *) ((*s_nouvel_objet).objet))) .position_clef = (*((struct_fichier *) ((*s_objet).objet))).position_clef; (*((struct_fichier *) ((*s_nouvel_objet).objet))).pid = (*((struct_fichier *) ((*s_objet).objet))).pid; (*((struct_fichier *) ((*s_nouvel_objet).objet))).tid = (*((struct_fichier *) ((*s_objet).objet))).tid; if (((*((struct_fichier *) ((*s_nouvel_objet).objet))).format = copie_objet(s_etat_processus, (*((struct_fichier *) ((*s_objet).objet))).format, type)) == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } if (((*((struct_fichier *) ((*s_nouvel_objet).objet))).nom = (unsigned char *) malloc((strlen((*((struct_fichier *) ((*s_objet).objet))).nom) + 1) * sizeof(unsigned char))) == NULL) { liberation(s_etat_processus, (*((struct_fichier *) (*s_nouvel_objet).objet)).format); free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } strcpy((*((struct_fichier *) ((*s_nouvel_objet).objet))).nom, (*((struct_fichier *) ((*s_objet).objet))).nom); break; } case FCT : { if (type != 'O') { /* * Remise à zéro de la prédiction pour respecter la cohérence * du saut dans les cas EXSUB et OBSUB. */ (*((struct_fonction *) ((*s_objet).objet))) .prediction_saut = NULL; incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, FCT)) == NULL) { return(NULL); } if (((*((struct_fonction *) ((*s_nouvel_objet).objet))) .nom_fonction = (unsigned char *) malloc((strlen((*((struct_fonction *) ((*s_objet).objet))).nom_fonction) + 1) * sizeof(unsigned char))) == NULL) { free(s_nouvel_objet); return(NULL); } strcpy((unsigned char *) (*((struct_fonction *) ((*s_nouvel_objet).objet))).nom_fonction, (unsigned char *) (*((struct_fonction *) ((*s_objet).objet))).nom_fonction); (*((struct_fonction *) ((*s_nouvel_objet).objet))) .nombre_arguments = (*((struct_fonction *) ((*s_objet).objet))).nombre_arguments; (*((struct_fonction *) ((*s_nouvel_objet).objet))).fonction = (*((struct_fonction *) ((*s_objet).objet))).fonction; break; } case INT : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, INT)) == NULL) { return(NULL); } (*((integer8 *) ((*s_nouvel_objet).objet))) = (*((integer8 *) ((*s_objet).objet))); break; } case LST : { if (type != 'P') { if ((s_nouvel_objet = allocation(s_etat_processus, LST)) == NULL) { return(NULL); } l_element_courant_lecture = (struct_liste_chainee *) ((*s_objet).objet); l_element_base = NULL; l_element_courant_ecriture = l_element_base; while(l_element_courant_lecture != NULL) { s_objet_tampon = copie_objet(s_etat_processus, (*l_element_courant_lecture).donnee, type); l_element_suivant_ecriture = (struct_liste_chainee *) malloc(sizeof(struct_liste_chainee)); if ((s_objet_tampon == NULL) || (l_element_suivant_ecriture == NULL)) { l_element_courant_lecture = (struct_liste_chainee *) ((*s_nouvel_objet).objet); while(l_element_courant_lecture != NULL) { l_element_suivant_lecture = (*l_element_courant_lecture).suivant; liberation(s_etat_processus, (*l_element_courant_lecture).donnee); free(l_element_courant_lecture); l_element_courant_lecture = l_element_suivant_lecture; } return(NULL); } if (l_element_courant_ecriture == NULL) { l_element_base = l_element_suivant_ecriture; } else { (*l_element_courant_ecriture).suivant = l_element_suivant_ecriture; } l_element_courant_ecriture = l_element_suivant_ecriture; (*l_element_courant_ecriture).donnee = s_objet_tampon; (*l_element_courant_ecriture).suivant = NULL; l_element_courant_lecture = (*l_element_courant_lecture).suivant; } (*s_nouvel_objet).objet = ((struct_liste_chainee *) l_element_base); } else { incrementation_atomique(s_objet); l_element_courant = (*s_objet).objet; while(l_element_courant != NULL) { (*l_element_courant).donnee = copie_objet(s_etat_processus, (*l_element_courant).donnee, 'P'); l_element_courant = (*l_element_courant).suivant; } return(s_objet); } break; } case MIN : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, MIN)) == NULL) { return(NULL); } (*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau = malloc(((size_t) ((*((struct_matrice *) ((*s_objet).objet))).nombre_lignes)) * sizeof(integer8 *)); if ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_colonnes = (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes; (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_lignes = (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; (*((struct_matrice *) ((*s_nouvel_objet).objet))).type = (*((struct_matrice *) ((*s_objet).objet))).type; for(i = 0; i < (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; i++) { if ((((integer8 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[i] = ((integer8 *) malloc(((size_t) ((*((struct_matrice *) ((*s_objet).objet))) .nombre_colonnes)) * sizeof(integer8)))) == NULL) { for(j = 0; j < i; j++) { free(((integer8 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[j]); } free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } for(j = 0; j < (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes; j++) { ((integer8 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[i][j] = ((integer8 **) ((*((struct_matrice *) ((*s_objet).objet))).tableau))[i][j]; } } break; } case MCX : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, MCX)) == NULL) { return(NULL); } (*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau = malloc(((size_t) ((*((struct_matrice *) ((*s_objet).objet))).nombre_lignes)) * sizeof(struct_complexe16 *)); if ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_colonnes = (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes; (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_lignes = (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; (*((struct_matrice *) ((*s_nouvel_objet).objet))).type = (*((struct_matrice *) ((*s_objet).objet))).type; for(i = 0; i < (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; i++) { if ((((struct_complexe16 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[i] = ((struct_complexe16 *) malloc(((size_t) ((*((struct_matrice *) ((*s_objet).objet))) .nombre_colonnes)) * sizeof(struct_complexe16)))) == NULL) { for(j = 0; j < i; j++) { free(((struct_complexe16 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[j]); } free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } for(j = 0; j < (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes; j++) { ((struct_complexe16 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[i][j] = ((struct_complexe16 **) ((*((struct_matrice *) ((*s_objet).objet))).tableau))[i][j]; } } break; } case MRL : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, MRL)) == NULL) { return(NULL); } (*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau = malloc(((size_t) ((*((struct_matrice *) ((*s_objet).objet))).nombre_lignes)) * sizeof(real8 *)); if ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_colonnes = (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes; (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_lignes = (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; (*((struct_matrice *) ((*s_nouvel_objet).objet))).type = (*((struct_matrice *) ((*s_objet).objet))).type; for(i = 0; i < (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes; i++) { if ((((real8 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[i] = ((real8 *) malloc(((size_t) ((*((struct_matrice *) ((*s_objet).objet))) .nombre_colonnes)) * sizeof(real8)))) == NULL) { for(j = 0; j < i; j++) { free(((real8 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[j]); } free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } for(j = 0; j < (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes; j++) { ((real8 **) ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau))[i][j] = ((real8 **) ((*((struct_matrice *) ((*s_objet).objet))).tableau))[i][j]; } } break; } case MTX : { // La duplication d'un mutex renvoie le même objet. incrementation_atomique(s_objet); return(s_objet); } case NOM : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, NOM)) == NULL) { return(NULL); } (*((struct_nom *) (*s_nouvel_objet).objet)).nom = malloc(( strlen((*((struct_nom *) (*s_objet).objet)).nom) + 1) * sizeof(unsigned char)); if ((*((struct_nom *) (*s_nouvel_objet).objet)).nom == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } strcpy((*((struct_nom *) (*s_nouvel_objet).objet)).nom, (*((struct_nom *) (*s_objet).objet)).nom); (*((struct_nom *) (*s_nouvel_objet).objet)).symbole = (*((struct_nom *) (*s_objet).objet)).symbole; break; } case NON : { if (type != 'O') { incrementation_atomique(s_objet); 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 = (*s_objet).objet; break; } case PRC : { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { return(NULL); } (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .nombre_references++; if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { return(NULL); } if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, PRC)) == NULL) { return(NULL); } (*((struct_processus_fils *) (*s_nouvel_objet).objet)) = (*((struct_processus_fils *) (*s_objet).objet)); break; } case REC : { if (type != 'P') { if ((s_nouvel_objet = allocation(s_etat_processus, REC)) == NULL) { return(NULL); } if (((*((struct_record *) (*s_nouvel_objet).objet)).noms = copie_objet(s_etat_processus, (*((struct_record *) (*s_objet).objet)).noms, 'P')) == NULL) { return(NULL); } if (((*((struct_record *) (*s_nouvel_objet).objet)).donnees = copie_objet(s_etat_processus, (*((struct_record *) (*s_objet).objet)).donnees, type)) == NULL) { return(NULL); } } else { incrementation_atomique(s_objet); (*((struct_record *) (*s_objet).objet)).noms = copie_objet(s_etat_processus, (*((struct_record *) (*s_objet).objet)).noms, 'P'); (*((struct_record *) (*s_objet).objet)).donnees = copie_objet(s_etat_processus, (*((struct_record *) (*s_objet).objet)).donnees, 'P'); return(s_objet); } break; } case REL : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, REL)) == NULL) { return(NULL); } (*((real8 *) ((*s_nouvel_objet).objet))) = (*((real8 *) ((*s_objet).objet))); break; } case SCK : { if (type == 'P') { incrementation_atomique(s_objet); if (((*((struct_socket *) ((*s_objet).objet))) .format = copie_objet(s_etat_processus, (*((struct_socket *) ((*s_objet).objet))).format, 'P')) == NULL) { return(NULL); } return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, SCK)) == NULL) { return(NULL); } (*((struct_socket *) ((*s_nouvel_objet).objet))).socket = (*((struct_socket *) ((*s_objet).objet))).socket; (*((struct_socket *) ((*s_nouvel_objet).objet))).domaine = (*((struct_socket *) ((*s_objet).objet))).domaine; (*((struct_socket *) ((*s_nouvel_objet).objet))).socket_en_ecoute = (*((struct_socket *) ((*s_objet).objet))).socket_en_ecoute; (*((struct_socket *) ((*s_nouvel_objet).objet))).socket_connectee = (*((struct_socket *) ((*s_objet).objet))).socket_connectee; (*((struct_socket *) ((*s_nouvel_objet).objet))).pid = (*((struct_socket *) ((*s_objet).objet))).pid; (*((struct_socket *) ((*s_nouvel_objet).objet))).binaire = (*((struct_socket *) ((*s_objet).objet))).binaire; (*((struct_socket *) ((*s_nouvel_objet).objet))).effacement = (*((struct_socket *) ((*s_objet).objet))).effacement; (*((struct_socket *) ((*s_nouvel_objet).objet))).protection = (*((struct_socket *) ((*s_objet).objet))).protection; (*((struct_socket *) ((*s_nouvel_objet).objet))).localisation = (*((struct_socket *) ((*s_objet).objet))).localisation; (*((struct_socket *) ((*s_nouvel_objet).objet))).pid = (*((struct_socket *) ((*s_objet).objet))).pid; (*((struct_socket *) ((*s_nouvel_objet).objet))).tid = (*((struct_socket *) ((*s_objet).objet))).tid; (*((struct_socket *) ((*s_nouvel_objet).objet))).options = (*((struct_socket *) ((*s_objet).objet))).options; (*((struct_socket *) ((*s_nouvel_objet).objet))).priorite = (*((struct_socket *) ((*s_objet).objet))).priorite; (*((struct_socket *) ((*s_nouvel_objet).objet))).buffer_reception = (*((struct_socket *) ((*s_objet).objet))).buffer_reception; (*((struct_socket *) ((*s_nouvel_objet).objet))).buffer_emission = (*((struct_socket *) ((*s_objet).objet))).buffer_emission; (*((struct_socket *) ((*s_nouvel_objet).objet))).timeout_reception = (*((struct_socket *) ((*s_objet).objet))).timeout_reception; (*((struct_socket *) ((*s_nouvel_objet).objet))).timeout_emission = (*((struct_socket *) ((*s_objet).objet))).timeout_emission; if (((*((struct_socket *) ((*s_nouvel_objet).objet))).format = copie_objet(s_etat_processus, (*((struct_socket *) ((*s_objet).objet))).format, type)) == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } if (((*((struct_socket *) ((*s_nouvel_objet).objet))).adresse = (unsigned char *) malloc((strlen((*((struct_socket *) ((*s_objet).objet))).adresse) + 1) * sizeof(unsigned char))) == NULL) { liberation(s_etat_processus, (*((struct_fichier *) (*s_nouvel_objet).objet)).format); free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } strcpy((*((struct_socket *) ((*s_nouvel_objet).objet))) .adresse, (*((struct_socket *) ((*s_objet).objet))) .adresse); if (((*((struct_socket *) ((*s_nouvel_objet).objet))) .adresse_distante = malloc((strlen((*((struct_socket *) ((*s_objet).objet))).adresse_distante) + 1) * sizeof(unsigned char))) == NULL) { liberation(s_etat_processus, (*((struct_fichier *) (*s_nouvel_objet).objet)).format); free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } strcpy((*((struct_socket *) ((*s_nouvel_objet).objet))) .adresse_distante, (*((struct_socket *) ((*s_objet).objet))) .adresse_distante); strcpy((*((struct_socket *) ((*s_nouvel_objet).objet))).type, (*((struct_socket *) ((*s_objet).objet))).type); break; } case SLB : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, SLB)) == NULL) { return(NULL); } if (((*((struct_bibliotheque *) ((*s_nouvel_objet).objet))).nom = (unsigned char *) malloc((strlen((*((struct_bibliotheque *) ((*s_objet).objet))).nom) + 1) * sizeof(unsigned char))) == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } strcpy((*((struct_bibliotheque *) ((*s_nouvel_objet).objet))).nom, (*((struct_bibliotheque *) ((*s_objet).objet))).nom); /* * C'est objet est non modifiable et est un pointeur * sur un objet système. Seul la référence est copiée. */ (*((struct_bibliotheque *) (*s_nouvel_objet).objet)).descripteur = (*((struct_bibliotheque *) (*s_objet).objet)).descripteur; (*((struct_bibliotheque *) (*s_nouvel_objet).objet)).pid = (*((struct_bibliotheque *) (*s_objet).objet)).pid; (*((struct_bibliotheque *) (*s_nouvel_objet).objet)).tid = (*((struct_bibliotheque *) (*s_objet).objet)).tid; break; } case SPH : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, SPH)) == NULL) { return(NULL); } if (((*((struct_semaphore *) (*s_nouvel_objet).objet)).nom = malloc((strlen((*((struct_semaphore *) (*s_objet).objet)) .nom) + 1) * sizeof(unsigned char))) == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); 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; } case SQL : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, SQL)) == NULL) { return(NULL); } (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).pid = (*((struct_connecteur_sql *) (*s_objet).objet)).pid; (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).tid = (*((struct_connecteur_sql *) (*s_objet).objet)).tid; (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).descripteur = (*((struct_connecteur_sql *) (*s_objet).objet)).descripteur; if (((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).type = malloc((strlen((*((struct_connecteur_sql *) (*s_objet).objet)).type) + 1) * sizeof(unsigned char))) == NULL) { free(s_nouvel_objet); return(NULL); } strcpy((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).type, (*((struct_connecteur_sql *) (*s_objet).objet)).type); if ((*((struct_connecteur_sql *) (*s_objet).objet)).locale != NULL) { if (((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)) .locale = malloc((strlen((*((struct_connecteur_sql *) (*s_objet).objet)).locale) + 1) * sizeof(unsigned char))) == NULL) { free((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)) .locale); free(s_nouvel_objet); return(NULL); } strcpy((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)) .locale, (*((struct_connecteur_sql *) (*s_objet).objet)).locale); } else { (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).locale = NULL; } break; } case TBL : { if (type != 'P') { if ((s_nouvel_objet = allocation(s_etat_processus, TBL)) == NULL) { return(NULL); } (*((struct_tableau *) (*s_nouvel_objet).objet)) .nombre_elements = (*((struct_tableau *) (*s_objet).objet)).nombre_elements; if (((*((struct_tableau *) (*s_nouvel_objet).objet)).elements = malloc(((size_t) (*((struct_tableau *) (*s_objet).objet)).nombre_elements) * sizeof(struct_objet *))) == NULL) { return(NULL); } for(i = 0; i < (*((struct_tableau *) (*s_objet).objet)) .nombre_elements; i++) { if (((*((struct_tableau *) (*s_nouvel_objet).objet)) .elements[i] = copie_objet(s_etat_processus, (*((struct_tableau *) (*s_objet).objet)) .elements[i], type)) == NULL) { for(j = 0; j < i; j++) { liberation(s_etat_processus, (*((struct_tableau *) (*s_nouvel_objet).objet)).elements[j]); } free((*((struct_tableau *) (*s_nouvel_objet).objet)) .elements); free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } } } else { incrementation_atomique(s_objet); for(i = 0; i < (*((struct_tableau *) (*s_objet).objet)) .nombre_elements; i++) { (*((struct_tableau *) (*s_objet).objet)).elements[i] = copie_objet(s_etat_processus, (*((struct_tableau *) (*s_objet).objet)).elements[i], 'P'); } return(s_objet); } break; } case VIN : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, VIN)) == NULL) { return(NULL); } (*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau = ((integer8 *) malloc(((size_t) ((*((struct_vecteur *) ((*s_objet).objet))).taille)) * sizeof(integer8))); if ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } (*((struct_vecteur *) ((*s_nouvel_objet).objet))).taille = (*((struct_vecteur *) ((*s_objet).objet))).taille; (*((struct_vecteur *) ((*s_nouvel_objet).objet))).type = (*((struct_vecteur *) ((*s_objet).objet))).type; for(i = 0; i < (*((struct_vecteur *) ((*s_objet).objet))).taille; i++) { ((integer8 *) ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau))[i] = ((integer8 *) ((*((struct_vecteur *) ((*s_objet).objet))).tableau))[i]; } break; } case VCX : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, VCX)) == NULL) { return(NULL); } (*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau = ((struct_complexe16 *) malloc(((size_t) ((*((struct_vecteur *) ((*s_objet).objet))).taille)) * sizeof(struct_complexe16))); if ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } (*((struct_vecteur *) ((*s_nouvel_objet).objet))).taille = (*((struct_vecteur *) ((*s_objet).objet))).taille; (*((struct_vecteur *) ((*s_nouvel_objet).objet))).type = (*((struct_vecteur *) ((*s_objet).objet))).type; for(i = 0; i < (*((struct_vecteur *) ((*s_objet).objet))).taille; i++) { ((struct_complexe16 *) ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau))[i] = ((struct_complexe16 *) ((*((struct_vecteur *) ((*s_objet).objet))).tableau))[i]; } break; } case VRL : { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } if ((s_nouvel_objet = allocation(s_etat_processus, VRL)) == NULL) { return(NULL); } (*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau = ((real8 *) malloc(((size_t) ((*((struct_vecteur *) ((*s_objet).objet))).taille)) * sizeof(real8))); if ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau == NULL) { free((*s_nouvel_objet).objet); free(s_nouvel_objet); return(NULL); } (*((struct_vecteur *) ((*s_nouvel_objet).objet))).taille = (*((struct_vecteur *) ((*s_objet).objet))).taille; (*((struct_vecteur *) ((*s_nouvel_objet).objet))).type = (*((struct_vecteur *) ((*s_objet).objet))).type; for(i = 0; i < (*((struct_vecteur *) ((*s_objet).objet))).taille; i++) { ((real8 *) ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau))[i] = ((real8 *) ((*((struct_vecteur *) ((*s_objet).objet))).tableau))[i]; } break; } case EXT: { if (type != 'O') { incrementation_atomique(s_objet); return(s_objet); } // Appel de la fonction de duplication associée à l'objet // externe. Le descripteur de bibliothèque est directement // associé à la structure objet. l_element_courant = (*s_etat_processus).s_bibliotheques; while(l_element_courant != NULL) { if ((*((struct_bibliotheque *) (*l_element_courant).donnee)) .descripteur == (*s_objet).descripteur_bibliotheque) { if ((__type_dup = dlsym((*s_objet).descripteur_bibliotheque, "__type_dup")) == NULL) { // La fonction de duplication n'existe pas dans la // bibliothèque. (*s_etat_processus).erreur_execution = d_ex_type_externe_dup; return(NULL); } s_nouvel_objet = s_objet; if (__type_dup(s_etat_processus, (void **) &s_nouvel_objet) == 0) { return(NULL); } break; } l_element_courant = (*l_element_courant).suivant; } if (l_element_courant == NULL) { (*s_etat_processus).erreur_execution = d_ex_type_externe_dup; return(NULL); } break; } default : { return(NULL); } } return(s_nouvel_objet); #undef return } /* ================================================================================ Routine de copie d'une structure de description d'un processus ================================================================================ Entrées : pointeur sur la structure de description d'un processus -------------------------------------------------------------------------------- Sorties : structure identique (tous les objets sont copiés) -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ struct_processus * copie_etat_processus(struct_processus *s_etat_processus) { pthread_mutexattr_t attributs_mutex; struct_liste_chainee *l_element_lecture; struct_liste_chainee *l_element_precedent; struct_liste_chainee *l_element_suivant; struct_processus *s_nouvel_etat_processus; integer8 i; if (pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } if ((s_nouvel_etat_processus = sys_malloc(sizeof(struct_processus))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } if (pthread_mutex_lock(&((*s_etat_processus).mutex_interruptions)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_nouvel_etat_processus) = (*s_etat_processus); if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } if (pthread_mutex_unlock(&((*s_etat_processus).mutex_interruptions)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } // On réinitialise les allocateurs. pthread_mutexattr_init(&attributs_mutex); pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&((*s_nouvel_etat_processus).mutex_allocation_buffer), &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); initialisation_allocateur(s_nouvel_etat_processus); initialisation_allocateur_buffer(s_nouvel_etat_processus); /* * (*s_etat_processus).definition_chainee, * (*s_etat_processus).nom_fichier_source, * (*s_etat_processus).nom_fichier_historique et * (*s_etat_processus).chemin_fichier_temporaires * n'ont aucune raison de changer. */ (*s_nouvel_etat_processus).sections_critiques = 0; (*s_nouvel_etat_processus).initialisation_scheduler = d_faux; // 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; (*s_nouvel_etat_processus).requete_nouveau_plan = d_vrai; (*s_nouvel_etat_processus).mise_a_jour_trace_requise = d_faux; (*s_nouvel_etat_processus).nom_fichier_impression = NULL; (*s_nouvel_etat_processus).expression_courante = NULL; (*s_nouvel_etat_processus).objet_courant = NULL; (*s_nouvel_etat_processus).processus_detache = d_faux; (*s_nouvel_etat_processus).evaluation_forcee = 'N'; (*s_nouvel_etat_processus).nombre_objets_envoyes_non_lus = 0; (*s_nouvel_etat_processus).nombre_objets_injectes = 0; (*s_nouvel_etat_processus).presence_fusible = d_faux; (*s_nouvel_etat_processus).thread_fusible = 0; (*s_nouvel_etat_processus).niveau_initial = (*s_etat_processus).niveau_courant; (*s_nouvel_etat_processus).presence_pipes = d_faux; (*s_nouvel_etat_processus).debug_programme = d_faux; (*s_nouvel_etat_processus).s_fichiers = NULL; (*s_nouvel_etat_processus).s_connecteurs_sql = NULL; // On réinitialise toutes les interruptions. (*s_nouvel_etat_processus).traitement_interruption = 'N'; (*s_nouvel_etat_processus).traitement_interruptible = 'Y'; (*s_nouvel_etat_processus).nombre_interruptions_en_queue = 0; (*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++) { (*s_nouvel_etat_processus).corps_interruptions[i] = NULL; (*s_nouvel_etat_processus).masque_interruptions[i] = 'N'; (*s_nouvel_etat_processus).queue_interruptions[i] = 0; (*s_nouvel_etat_processus).pile_origine_interruptions[i] = NULL; } if ((*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); } gsl_rng_set((*s_nouvel_etat_processus).generateur_aleatoire, gsl_rng_get((*s_etat_processus).generateur_aleatoire)); } // Copie de la localisation if (((*s_nouvel_etat_processus).localisation = rpl_malloc( s_nouvel_etat_processus, (strlen((*s_etat_processus).localisation) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } strcpy((*s_nouvel_etat_processus).localisation, (*s_etat_processus).localisation); if ((*s_etat_processus).indep != NULL) { if (((*s_nouvel_etat_processus).indep = copie_objet(s_etat_processus, (*s_etat_processus).indep, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } } else { (*s_nouvel_etat_processus).indep = NULL; } if ((*s_etat_processus).depend != NULL) { if (((*s_nouvel_etat_processus).depend = copie_objet(s_etat_processus, (*s_etat_processus).depend, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } } else { (*s_nouvel_etat_processus).depend = NULL; } if ((*s_etat_processus).parametres_courbes_de_niveau != NULL) { if (((*s_nouvel_etat_processus).parametres_courbes_de_niveau = copie_objet(s_etat_processus, (*s_etat_processus) .parametres_courbes_de_niveau, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } } else { (*s_nouvel_etat_processus).parametres_courbes_de_niveau = NULL; } (*s_nouvel_etat_processus).instruction_derniere_erreur = NULL; if (((*s_etat_processus).instruction_courante != NULL) && (*s_etat_processus).evaluation_expression_compilee == 'N') { if (((*s_nouvel_etat_processus).instruction_courante = rpl_malloc( s_nouvel_etat_processus, (strlen( (*s_etat_processus).instruction_courante) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 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).instruction_courante, (*s_etat_processus).instruction_courante); } else { (*s_nouvel_etat_processus).instruction_courante = NULL; } if ((*s_etat_processus).label_x != NULL) { if (((*s_nouvel_etat_processus).label_x = rpl_malloc( s_nouvel_etat_processus, (strlen( (*s_etat_processus).label_x) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 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).label_x, (*s_etat_processus).label_x); } else { (*s_nouvel_etat_processus).label_x = NULL; } if ((*s_etat_processus).label_y != NULL) { if (((*s_nouvel_etat_processus).label_y = rpl_malloc( s_nouvel_etat_processus, (strlen((*s_etat_processus).label_y) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 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).label_y, (*s_etat_processus).label_y); } else { (*s_nouvel_etat_processus).label_y = NULL; } if ((*s_etat_processus).label_z != NULL) { if (((*s_nouvel_etat_processus).label_z = rpl_malloc( s_nouvel_etat_processus, (strlen((*s_etat_processus).label_z) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 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).label_z, (*s_etat_processus).label_z); } else { (*s_nouvel_etat_processus).label_z = NULL; } if ((*s_etat_processus).titre != NULL) { if (((*s_nouvel_etat_processus).titre = rpl_malloc( s_nouvel_etat_processus, (strlen((*s_etat_processus).titre) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 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).titre, (*s_etat_processus).titre); } else { (*s_nouvel_etat_processus).titre = NULL; } if ((*s_etat_processus).legende != NULL) { if (((*s_nouvel_etat_processus).legende = rpl_malloc( s_nouvel_etat_processus, (strlen((*s_etat_processus).legende) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 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).legende, (*s_etat_processus).legende); } else { (*s_nouvel_etat_processus).legende = NULL; } /* * Copie de la table des variables */ (*s_nouvel_etat_processus).l_liste_variables_statiques = NULL; copie_arbre_variables(s_etat_processus, s_nouvel_etat_processus); if ((*s_nouvel_etat_processus).erreur_systeme != d_es) { return(NULL); } (*(*s_nouvel_etat_processus).l_liste_variables_partagees) = (*(*s_etat_processus).l_liste_variables_partagees); (*(*s_nouvel_etat_processus).s_arbre_variables_partagees) = (*(*s_etat_processus).s_arbre_variables_partagees); /* * Copie de la pile opérationnelle */ (*s_nouvel_etat_processus).l_base_pile = NULL; l_element_lecture = (*s_etat_processus).l_base_pile; l_element_precedent = NULL; while(l_element_lecture != NULL) { if ((l_element_suivant = rpl_malloc(s_nouvel_etat_processus, sizeof(struct_liste_chainee))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } if (((*l_element_suivant).donnee = copie_objet(s_etat_processus, (*l_element_lecture).donnee, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*l_element_suivant).suivant = NULL; if ((*s_nouvel_etat_processus).l_base_pile == NULL) { (*s_nouvel_etat_processus).l_base_pile = l_element_suivant; } else { (*l_element_precedent).suivant = l_element_suivant; } l_element_precedent = l_element_suivant; l_element_lecture = (*l_element_lecture).suivant; } /* * Copie de la pile système */ (*s_nouvel_etat_processus).l_base_pile_systeme = NULL; (*s_nouvel_etat_processus).hauteur_pile_systeme = 0; empilement_pile_systeme(s_nouvel_etat_processus); if ((*s_nouvel_etat_processus).erreur_systeme != d_es) { if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = (*s_nouvel_etat_processus).erreur_systeme; return(NULL); } (*(*s_nouvel_etat_processus).l_base_pile_systeme).retour_definition = 'Y'; /* * On empile deux valeurs retour_definition pour pouvoir récupérer * les variables dans le cas d'un programme compilé. */ empilement_pile_systeme(s_nouvel_etat_processus); if ((*s_nouvel_etat_processus).erreur_systeme != d_es) { if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = (*s_nouvel_etat_processus).erreur_systeme; return(NULL); } (*(*s_nouvel_etat_processus).l_base_pile_systeme).retour_definition = 'Y'; /* * Destruction de la pile last pour le thread en cours. */ (*s_nouvel_etat_processus).l_base_pile_last = NULL; (*s_nouvel_etat_processus).l_base_pile_processus = NULL; /* * 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; while(l_element_lecture != NULL) { if ((l_element_suivant = rpl_malloc(s_nouvel_etat_processus, sizeof(struct_liste_chainee))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } if (((*l_element_suivant).donnee = copie_objet(s_etat_processus, (*l_element_lecture).donnee, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*l_element_suivant).suivant = NULL; if ((*s_nouvel_etat_processus).l_base_pile_contextes == NULL) { (*s_nouvel_etat_processus).l_base_pile_contextes = l_element_suivant; } else { (*l_element_precedent).suivant = l_element_suivant; } l_element_precedent = l_element_suivant; l_element_lecture = (*l_element_lecture).suivant; } (*s_nouvel_etat_processus).l_base_pile_taille_contextes = NULL; l_element_lecture = (*s_etat_processus).l_base_pile_taille_contextes; while(l_element_lecture != NULL) { if ((l_element_suivant = rpl_malloc(s_nouvel_etat_processus, sizeof(struct_liste_chainee))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } if (((*l_element_suivant).donnee = copie_objet(s_etat_processus, (*l_element_lecture).donnee, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*l_element_suivant).suivant = NULL; if ((*s_nouvel_etat_processus).l_base_pile_taille_contextes == NULL) { (*s_nouvel_etat_processus).l_base_pile_taille_contextes = l_element_suivant; } else { (*l_element_precedent).suivant = l_element_suivant; } l_element_precedent = l_element_suivant; l_element_lecture = (*l_element_lecture).suivant; } /* * Copies des piles s_sockets, s_bibliotheques et * s_instructions_externes. */ (*s_nouvel_etat_processus).s_sockets = NULL; l_element_lecture = (*s_etat_processus).s_sockets; while(l_element_lecture != NULL) { if ((l_element_suivant = rpl_malloc(s_nouvel_etat_processus, sizeof(struct_liste_chainee))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } if (((*l_element_suivant).donnee = copie_objet(s_etat_processus, (*l_element_lecture).donnee, 'P')) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*l_element_suivant).suivant = NULL; if ((*s_nouvel_etat_processus).s_sockets == NULL) { (*s_nouvel_etat_processus).s_sockets = l_element_suivant; } else { (*l_element_precedent).suivant = l_element_suivant; } l_element_precedent = l_element_suivant; l_element_lecture = (*l_element_lecture).suivant; } (*s_nouvel_etat_processus).s_bibliotheques = NULL; l_element_precedent = NULL; l_element_lecture = (*s_etat_processus).s_bibliotheques; while(l_element_lecture != NULL) { if ((l_element_suivant = rpl_malloc(s_nouvel_etat_processus, sizeof(struct_liste_chainee))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } if (((*l_element_suivant).donnee = rpl_malloc(s_nouvel_etat_processus, sizeof(struct_bibliotheque))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_bibliotheque *) (*l_element_suivant).donnee)).descripteur = (*((struct_bibliotheque *) (*l_element_lecture).donnee)) .descripteur; (*((struct_bibliotheque *) (*l_element_suivant).donnee)).pid = (*((struct_bibliotheque *) (*l_element_lecture).donnee)).pid; (*((struct_bibliotheque *) (*l_element_suivant).donnee)).tid = (*((struct_bibliotheque *) (*l_element_lecture).donnee)).tid; if (((*((struct_bibliotheque *) (*l_element_suivant).donnee)).nom = rpl_malloc(s_nouvel_etat_processus, (strlen((*((struct_bibliotheque *) (*l_element_lecture) .donnee)).nom) + 1) * sizeof(unsigned char))) == NULL) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } strcpy((*((struct_bibliotheque *) (*l_element_suivant).donnee)).nom, (*((struct_bibliotheque *) (*l_element_lecture).donnee)).nom); (*l_element_suivant).suivant = NULL; if ((*s_nouvel_etat_processus).s_bibliotheques == NULL) { (*s_nouvel_etat_processus).s_bibliotheques = l_element_suivant; } else { (*l_element_precedent).suivant = l_element_suivant; } l_element_precedent = l_element_suivant; l_element_lecture = (*l_element_lecture).suivant; } if ((*s_etat_processus).nombre_instructions_externes != 0) { if (((*s_nouvel_etat_processus).s_instructions_externes = rpl_malloc(s_nouvel_etat_processus, ((size_t) (*s_etat_processus).nombre_instructions_externes) * sizeof(struct_instruction_externe))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++) { if (((*s_nouvel_etat_processus).s_instructions_externes[i].nom = rpl_malloc(s_nouvel_etat_processus, (strlen((*s_etat_processus).s_instructions_externes [i].nom) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } strcpy((*s_nouvel_etat_processus).s_instructions_externes[i].nom, (*s_etat_processus).s_instructions_externes[i].nom); if (((*s_nouvel_etat_processus).s_instructions_externes[i] .nom_bibliotheque = rpl_malloc(s_nouvel_etat_processus, (strlen((*s_etat_processus).s_instructions_externes[i] .nom_bibliotheque) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } strcpy((*s_nouvel_etat_processus).s_instructions_externes[i] .nom_bibliotheque, (*s_etat_processus) .s_instructions_externes[i].nom_bibliotheque); (*s_nouvel_etat_processus).s_instructions_externes[i] .descripteur_bibliotheque = (*s_etat_processus) .s_instructions_externes[i].descripteur_bibliotheque; } } else { (*s_nouvel_etat_processus).s_instructions_externes = NULL; } pthread_mutexattr_init(&attributs_mutex); pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&((*s_nouvel_etat_processus).mutex_pile_processus), &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_interruptions), &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_signaux), &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).protection_liste_mutexes), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } return(s_nouvel_etat_processus); #undef return } /* ================================================================================ Routines de debug ================================================================================ entrées : -------------------------------------------------------------------------------- sorties : -------------------------------------------------------------------------------- effets de bord : néant ================================================================================ */ #ifdef DEBUG_MEMOIRE #undef malloc #undef realloc #undef free #undef fork #ifdef return # undef return #endif #ifdef __BACKTRACE #define PROFONDEUR_PILE 64 #define return(a) { if (a == NULL) \ { BACKTRACE(PROFONDEUR_PILE); \ fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \ return(a); } while(0) #endif #undef fprintf #define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b)) #undef CORE_DUMP typedef struct memoire { void *pointeur; unsigned char *fonction; unsigned char *argument; unsigned long ligne; size_t taille; unsigned long long ordre; # ifdef __BACKTRACE void *pile[PROFONDEUR_PILE]; int profondeur; # endif struct memoire *suivant; } struct_memoire; static struct_memoire *debug = NULL; static unsigned long long ordre = 0; static pthread_mutex_t mutex_allocation; 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, unsigned long ligne, const unsigned char *argument) { struct_memoire *ancienne_base; void *pointeur; pthread_mutex_lock(&mutex_allocation); ancienne_base = debug; if ((debug = malloc(sizeof(struct_memoire))) == NULL) { pthread_mutex_unlock(&mutex_allocation); return(NULL); } if (((*debug).pointeur = malloc(taille)) == NULL) { pthread_mutex_unlock(&mutex_allocation); return(NULL); } (*debug).suivant = ancienne_base; (*debug).ligne = ligne; (*debug).taille = taille; (*debug).ordre = ordre; pointeur = (*debug).pointeur; # ifdef __BACKTRACE (*debug).profondeur = backtrace((*debug).pile, PROFONDEUR_PILE); # endif if (((*debug).fonction = malloc((strlen(fonction) + 1) * sizeof(unsigned char))) == NULL) { pthread_mutex_unlock(&mutex_allocation); uprintf("[%d-%llu] ILLEGAL POINTER (malloc) $%016X\n", getpid(), (unsigned long long) pthread_self(), NULL); # ifdef __BACKTRACE BACKTRACE(PROFONDEUR_PILE); # endif return(NULL); } if (((*debug).argument = malloc((strlen(argument) + 1) * sizeof(unsigned char))) == NULL) { pthread_mutex_unlock(&mutex_allocation); return(NULL); } strcpy((*debug).fonction, fonction); strcpy((*debug).argument, argument); memset((*debug).pointeur, 0, (*debug).taille); pthread_mutex_unlock(&mutex_allocation); ordre++; return(pointeur); } void * debug_memoire_modification(void *pointeur, size_t taille, const unsigned char *fonction, unsigned long ligne, const unsigned char *argument) { struct_memoire *element_courant; if (pointeur != NULL) { if (taille == 0) { // 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 ; } else { // Réallocation réelle pthread_mutex_lock(&mutex_allocation); element_courant = debug; while(element_courant != NULL) { if ((*element_courant).pointeur == pointeur) { break; } element_courant = (*element_courant).suivant; } if (element_courant == NULL) { pthread_mutex_unlock(&mutex_allocation); uprintf("[%d-%llu] ILLEGAL POINTER (realloc) $%016X\n", getpid(), (unsigned long long) pthread_self(), pointeur); # 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); 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); } strcpy((*element_courant).fonction, fonction); strcpy((*element_courant).argument, argument); pthread_mutex_unlock(&mutex_allocation); return((*element_courant).pointeur); } } } else { // Revient à malloc() pointeur = debug_memoire_ajout(taille, fonction, ligne, argument); return(pointeur); } } void debug_memoire_retrait(void *pointeur) { struct_memoire *element_courant; struct_memoire *element_precedent; pthread_mutex_lock(&mutex_allocation); element_courant = debug; element_precedent = NULL; while(element_courant != NULL) { if ((*element_courant).pointeur == pointeur) { if (element_precedent == NULL) { debug = (*debug).suivant; } else { (*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); break; } element_precedent = element_courant; element_courant = (*element_courant).suivant; } pthread_mutex_unlock(&mutex_allocation); if (element_courant == NULL) { uprintf("[%d-%llu] ILLEGAL POINTER (free) $%016X\n", getpid(), (unsigned long long) pthread_self(), pointeur); # ifdef __BACKTRACE BACKTRACE(PROFONDEUR_PILE); # endif } free(pointeur); return; } void debug_memoire_verification() { # ifdef __BACKTRACE char **appels; int j; # endif integer8 i; struct_memoire *element_courant; struct_memoire *element_suivant; fprintf(stderr, "[%d-%llu] LIST OF MEMORY LEAKS\n", getpid(), (unsigned long long) pthread_self()); pthread_mutex_lock(&mutex_allocation); element_courant = debug; i = 1; while(element_courant != NULL) { fprintf(stderr, "[%d-%llu] MEDITATION %lld (%llu)\n", getpid(), (unsigned long long) pthread_self(), i, (*element_courant).ordre); fprintf(stderr, "[%d-%llu] P: %p, F: %s(), L: %lu, S: %d\n", getpid(), (unsigned long long) pthread_self(), (*element_courant).pointeur, (*element_courant).fonction, (*element_courant).ligne, (int) (*element_courant).taille); fprintf(stderr, "[%d-%llu] A: %s\n", getpid(), (unsigned long long) pthread_self(), (*element_courant).argument); if (strstr((*element_courant).argument, "sizeof(unsigned char)") != NULL) { fprintf(stderr, "[%d-%llu] ", getpid(), (unsigned long long) pthread_self()); fprintf(stderr, "O: %s\n", (unsigned char *) (*element_courant).pointeur); } else if (strcmp((*element_courant).argument, "sizeof(struct_objet)") == 0) { fprintf(stderr, "[%d-%llu] ", getpid(), (unsigned long long) pthread_self()); fprintf(stderr, "O: %d\n", (*((struct_objet *) (*element_courant).pointeur)).type); } else if (strcmp((*element_courant).argument, "sizeof(struct_liste_chainee)") == 0) { fprintf(stderr, "[%d-%llu] ", getpid(), (unsigned long long) pthread_self()); fprintf(stderr, "O: data=%p next=%p\n", (*((struct_liste_chainee *) (*element_courant).pointeur)).donnee, (*((struct_liste_chainee *) (*element_courant).pointeur)) .suivant); } # ifdef __BACKTRACE appels = backtrace_symbols((*element_courant).pile, (*element_courant).profondeur); fprintf(stderr, "[%d-%llu] BACKTRACE\n", getpid(), (unsigned long long) pthread_self()); if (appels != NULL) { for(j = 0; j < (*element_courant).profondeur; j++) { fprintf(stderr, "[%d-%llu] %s\n", getpid(), (unsigned long long) pthread_self(), appels[j]); } free(appels); } # endif fprintf(stderr, "\n"); i++; element_suivant = (*element_courant).suivant; # ifndef CORE_DUMP free((*element_courant).fonction); free((*element_courant).argument); free(element_courant); # endif element_courant = element_suivant; } pthread_mutex_unlock(&mutex_allocation); pthread_mutex_destroy(&mutex_allocation); fprintf(stderr, "[%d-%llu] END OF LIST\n", getpid(), (unsigned long long) pthread_self()); return; } pid_t debug_fork(struct_processus *s_etat_processus) { pid_t pid; pthread_mutex_lock(&mutex_allocation); pid = fork(); if (pid == 0) { liberation_queue_signaux(s_etat_processus); creation_queue_signaux(s_etat_processus); 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 analyse_post_mortem() { # ifdef CORE_DUMP BUG(debug != NULL, uprintf("[%d-%llu] CREATE CORE DUMP FILE FOR " "POST MORTEM ANALYZE\n", getpid(), (unsigned long long) pthread_self())); # endif return; } #endif // vim: ts=4