version 1.4, 2010/03/04 10:17:49
|
version 1.72, 2020/01/10 11:15:43
|
Line 1
|
Line 1
|
/* |
/* |
================================================================================ |
================================================================================ |
RPL/2 (R) version 4.0.12 |
RPL/2 (R) version 4.1.32 |
Copyright (C) 1989-2010 Dr. BERTRAND Joël |
Copyright (C) 1989-2020 Dr. BERTRAND Joël |
|
|
This file is part of RPL/2. |
This file is part of RPL/2. |
|
|
Line 20
|
Line 20
|
*/ |
*/ |
|
|
|
|
#include "rpl.conv.h" |
#include "rpl-conv.h" |
|
|
|
|
|
/* |
|
================================================================================ |
|
Routine de gestion du cache des objets |
|
================================================================================ |
|
Entrée : |
|
-------------------------------------------------------------------------------- |
|
Sortie : |
|
-------------------------------------------------------------------------------- |
|
Effets de bords : néant |
|
================================================================================ |
|
*/ |
|
|
|
static inline struct_arbre_variables_partagees * |
|
allocation_noeud_partage(struct_processus *s_etat_processus) |
|
{ |
|
struct_arbre_variables_partagees *objet; |
|
|
|
if ((*s_etat_processus).pointeur_variables_partagees_noeud > 0) |
|
{ |
|
objet = (*s_etat_processus).variables_partagees_noeud |
|
[--(*s_etat_processus).pointeur_variables_partagees_noeud]; |
|
} |
|
else |
|
{ |
|
objet = malloc(sizeof(struct_arbre_variables_partagees)); |
|
} |
|
|
|
return(objet); |
|
} |
|
|
|
static inline void |
|
liberation_noeud_partage(struct_processus *s_etat_processus, |
|
struct_arbre_variables_partagees *objet) |
|
{ |
|
if ((*s_etat_processus).pointeur_variables_partagees_noeud < TAILLE_CACHE) |
|
{ |
|
(*s_etat_processus).variables_partagees_noeud |
|
[(*s_etat_processus).pointeur_variables_partagees_noeud++] = |
|
objet; |
|
} |
|
else |
|
{ |
|
free(objet); |
|
} |
|
|
|
return; |
|
} |
|
|
|
static inline struct_arbre_variables_partagees ** |
|
allocation_tableau_noeuds_partages(struct_processus *s_etat_processus) |
|
{ |
|
struct_arbre_variables_partagees **objet; |
|
|
|
if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages > 0) |
|
{ |
|
objet = (*s_etat_processus).variables_tableau_noeuds_partages |
|
[--(*s_etat_processus) |
|
.pointeur_variables_tableau_noeuds_partages]; |
|
} |
|
else |
|
{ |
|
objet = malloc(((size_t) (*s_etat_processus) |
|
.nombre_caracteres_variables) |
|
* sizeof(struct_arbre_variables_partagees *)); |
|
} |
|
|
|
return(objet); |
|
} |
|
|
|
static inline void |
|
liberation_tableau_noeuds_partages(struct_processus *s_etat_processus, |
|
struct_arbre_variables_partagees **objet) |
|
{ |
|
if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages |
|
< TAILLE_CACHE) |
|
{ |
|
(*s_etat_processus).variables_tableau_noeuds_partages |
|
[(*s_etat_processus) |
|
.pointeur_variables_tableau_noeuds_partages++] = objet; |
|
} |
|
else |
|
{ |
|
free(objet); |
|
} |
|
|
|
return; |
|
} |
|
|
|
|
/* |
/* |
Line 39 logical1
|
Line 128 logical1
|
creation_variable_partagee(struct_processus *s_etat_processus, |
creation_variable_partagee(struct_processus *s_etat_processus, |
struct_variable_partagee *s_variable) |
struct_variable_partagee *s_variable) |
{ |
{ |
struct_variable_partagee *s_nouvelle_base; |
int i; |
|
|
long i; |
struct_arbre_variables_partagees *l_variable_courante; |
|
|
(*(*s_etat_processus).s_liste_variables_partagees).nombre_variables++; |
struct_liste_variables_partagees *l_nouvel_element; |
|
|
if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables > |
unsigned char *ptr; |
(*(*s_etat_processus).s_liste_variables_partagees) |
|
.nombre_variables_allouees) |
// Ajout de la variable en tête de la liste des variables partagées |
|
|
|
if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees))) |
|
== NULL) |
{ |
{ |
// La nouvelle variable partagée ne tient pas dans la table existante. |
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
// Il convient donc d'en augmenter la taille. |
return(d_erreur); |
|
} |
|
|
if ((*(*s_etat_processus).s_liste_variables_partagees) |
if (((*l_nouvel_element).variable = malloc(sizeof( |
.nombre_variables_allouees == 0) |
struct_variable_partagee))) == NULL) |
{ |
{ |
(*(*s_etat_processus).s_liste_variables_partagees) |
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
.nombre_variables_allouees = (*(*s_etat_processus) |
return(d_erreur); |
.s_liste_variables_partagees).nombre_variables; |
} |
} |
|
else |
(*(*l_nouvel_element).variable) = (*s_variable); |
|
(*l_nouvel_element).pid = getpid(); |
|
(*l_nouvel_element).tid = pthread_self(); |
|
|
|
if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*l_nouvel_element).suivant = (*(*s_etat_processus) |
|
.l_liste_variables_partagees); |
|
(*l_nouvel_element).precedent = NULL; |
|
|
|
if ((*(*s_etat_processus).l_liste_variables_partagees) != NULL) |
|
{ |
|
(**(*s_etat_processus).l_liste_variables_partagees).precedent |
|
= l_nouvel_element; |
|
} |
|
|
|
(*(*s_etat_processus).l_liste_variables_partagees) = l_nouvel_element; |
|
|
|
// Ajout de la variable à la feuille de l'arbre des variables partagees |
|
|
|
if ((*(*s_etat_processus).s_arbre_variables_partagees) == NULL) |
|
{ |
|
if (((*(*s_etat_processus).s_arbre_variables_partagees) = |
|
allocation_noeud_partage(s_etat_processus)) == NULL) |
{ |
{ |
while((*(*s_etat_processus).s_liste_variables_partagees) |
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
.nombre_variables > (*(*s_etat_processus) |
|
.s_liste_variables_partagees).nombre_variables_allouees) |
|
{ |
{ |
(*(*s_etat_processus).s_liste_variables_partagees) |
(*s_etat_processus).erreur_systeme = d_es_processus; |
.nombre_variables_allouees *= 2; |
return(d_erreur); |
} |
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
|
return(d_erreur); |
} |
} |
|
|
if ((s_nouvelle_base = realloc((struct_variable_partagee *) |
(**(*s_etat_processus).s_arbre_variables_partagees).feuille = NULL; |
(*(*s_etat_processus).s_liste_variables_partagees).table, |
(**(*s_etat_processus).s_arbre_variables_partagees) |
(*(*s_etat_processus).s_liste_variables_partagees) |
.noeuds_utilises = 0; |
.nombre_variables_allouees * |
(**(*s_etat_processus).s_arbre_variables_partagees).indice_tableau_pere |
sizeof(struct_variable_partagee))) == NULL) |
= -1; |
|
(**(*s_etat_processus).s_arbre_variables_partagees).noeud_pere = NULL; |
|
INITIALISATION_MUTEX((**(*s_etat_processus).s_arbre_variables_partagees) |
|
.mutex_feuille); |
|
|
|
if (((**(*s_etat_processus).s_arbre_variables_partagees).noeuds = |
|
allocation_tableau_noeuds_partages(s_etat_processus)) == NULL) |
{ |
{ |
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
(*(*s_etat_processus).s_liste_variables_partagees) |
|
.nombre_variables--; |
|
return(d_erreur); |
return(d_erreur); |
} |
} |
|
|
(*(*s_etat_processus).s_liste_variables_partagees).table = |
for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) |
s_nouvelle_base; |
{ |
|
(**(*s_etat_processus).s_arbre_variables_partagees).noeuds[i] = |
|
NULL; |
|
} |
} |
} |
|
|
/* |
l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees); |
* Positionnement de la variable partagée au bon endroit |
ptr = (*s_variable).nom; |
*/ |
|
|
|
if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables |
if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0) |
== 1) |
|
{ |
{ |
(*(*s_etat_processus).s_liste_variables_partagees).table[0] |
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
= (*s_variable); |
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
} |
} |
else |
|
|
while((*ptr) != d_code_fin_chaine) |
{ |
{ |
for(i = (*(*s_etat_processus).s_liste_variables_partagees) |
BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0, |
.nombre_variables - 2; i >= 0; i--) |
uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom, |
|
*ptr)); |
|
|
|
if ((*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]] == NULL) |
{ |
{ |
if (strcmp((*s_variable).nom, (*(*s_etat_processus) |
// Le noeud n'existe pas encore, on le crée et on le marque |
.s_liste_variables_partagees).table[i].nom) < 0) |
// comme utilisé dans la structure parente. |
|
|
|
if (((*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]] = |
|
allocation_noeud_partage(s_etat_processus)) == NULL) |
{ |
{ |
(*(*s_etat_processus).s_liste_variables_partagees).table[i + 1] |
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
= (*(*s_etat_processus).s_liste_variables_partagees) |
{ |
.table[i]; |
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
|
return(d_erreur); |
} |
} |
else |
|
|
(*l_variable_courante).noeuds_utilises++; |
|
|
|
// La feuille est par défaut vide et aucun élément du tableau noeuds |
|
// (les branches qui peuvent être issues de ce nouveau noeud) |
|
// n'est encore utilisée. |
|
|
|
(*(*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]]).feuille = NULL; |
|
(*(*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0; |
|
|
|
// Le champ noeud_pere de la structure créée pointe sur |
|
// la structure parente et l'indice tableau_pere correspond à la |
|
// position réelle dans le tableau noeuds[] de la structure parente |
|
// du noeud courant. Cette valeur sera utilisée lors de la |
|
// destruction du noeud pour annuler le pointeur contenu dans |
|
// le tableau noeuds[] de la structure parente. |
|
|
|
(*(*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]]).noeud_pere = |
|
l_variable_courante; |
|
(*(*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]]) |
|
.indice_tableau_pere = (*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]; |
|
INITIALISATION_MUTEX((*(*l_variable_courante).noeuds |
|
[(*s_etat_processus).pointeurs_caracteres_variables[*ptr]]) |
|
.mutex_feuille); |
|
|
|
// Allocation du tableau noeuds[] et initialisation à zéro de |
|
// tous les pointeurs. |
|
|
|
if (((*(*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]]).noeuds = |
|
allocation_tableau_noeuds_partages(s_etat_processus)) |
|
== NULL) |
|
{ |
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
|
return(d_erreur); |
|
} |
|
|
|
for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) |
{ |
{ |
break; |
(*(*l_variable_courante).noeuds[(*s_etat_processus) |
|
.pointeurs_caracteres_variables[*ptr]]).noeuds[i] |
|
= NULL; |
} |
} |
} |
} |
|
|
(*(*s_etat_processus).s_liste_variables_partagees).table[i + 1] |
if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds |
= (*s_variable); |
[(*s_etat_processus).pointeurs_caracteres_variables[*ptr]]) |
|
.mutex_feuille)) != 0) |
|
{ |
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0) |
|
{ |
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
l_variable_courante = (*l_variable_courante).noeuds |
|
[(*s_etat_processus).pointeurs_caracteres_variables[*ptr]]; |
|
ptr++; |
|
} |
|
|
|
if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees))) |
|
== NULL) |
|
{ |
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
|
return(d_erreur); |
|
} |
|
|
|
// Dans la feuille de l'arbre des variables partagées, on ne balaie |
|
// les variables que dans l'ordre. Le champ 'reference' est alors utilisé |
|
// pour sauvegarder une référence vers la liste des variables partagées |
|
// pour pouvoir purger l'élément en cas de besoin. |
|
|
|
(*l_nouvel_element).suivant = (*l_variable_courante).feuille; |
|
(*l_nouvel_element).precedent = NULL; |
|
|
|
if ((*l_nouvel_element).suivant != NULL) |
|
{ |
|
(*(*l_nouvel_element).suivant).precedent = l_nouvel_element; |
|
} |
|
|
|
(*l_nouvel_element).reference = |
|
(*(*s_etat_processus).l_liste_variables_partagees); |
|
(*l_nouvel_element).variable = (**(*s_etat_processus) |
|
.l_liste_variables_partagees).variable; |
|
(*l_variable_courante).feuille = l_nouvel_element; |
|
(*l_nouvel_element).feuille = l_variable_courante; |
|
|
|
if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0) |
|
{ |
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
} |
} |
|
|
return d_absence_erreur; |
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
|
return(d_absence_erreur); |
} |
} |
|
|
|
|
/* |
/* |
================================================================================ |
================================================================================ |
Procédure de retrait d'une variable partagee de la base |
Routine de recherche d'une variable partagée |
================================================================================ |
================================================================================ |
Entrée : |
Entrée : |
-------------------------------------------------------------------------------- |
-------------------------------------------------------------------------------- |
Sortie : |
Sortie : |
-------------------------------------------------------------------------------- |
-------------------------------------------------------------------------------- |
Effets de bord : néant |
Effets de bords : positionne le mutex sur la variable partagée |
================================================================================ |
================================================================================ |
*/ |
*/ |
|
|
logical1 |
struct_liste_variables_partagees * |
retrait_variable_partagee(struct_processus *s_etat_processus, |
recherche_variable_partagee(struct_processus *s_etat_processus, |
unsigned char *nom_variable, union_position_variable position) |
unsigned char *nom_variable, union_position_variable position, |
|
unsigned char origine) |
{ |
{ |
struct_variable_partagee *s_nouvelle_base; |
int pointeur; |
|
|
logical1 erreur; |
struct_arbre_variables_partagees *l_variable_courante; |
|
struct_liste_variables_partagees *l_element_courant; |
|
|
unsigned long position_courante; |
unsigned char *ptr; |
unsigned long position_supprimee; |
|
|
|
if (recherche_variable_partagee(s_etat_processus, nom_variable, |
l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees); |
position, ((*s_etat_processus).mode_execution_programme == 'Y') |
ptr = nom_variable; |
? 'P' : 'E') == d_vrai) |
|
|
if (l_variable_courante == NULL) |
{ |
{ |
if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables |
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
< ((*(*s_etat_processus).s_liste_variables_partagees) |
return(NULL); |
.nombre_variables_allouees / 2)) |
} |
{ |
|
(*(*s_etat_processus).s_liste_variables_partagees) |
|
.nombre_variables_allouees /= 2; |
|
|
|
if ((s_nouvelle_base = realloc((struct_variable_partagee *) |
if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0) |
(*(*s_etat_processus).s_liste_variables_partagees).table, |
{ |
(*(*s_etat_processus).s_liste_variables_partagees) |
(*s_etat_processus).erreur_systeme = d_es_processus; |
.nombre_variables_allouees * |
return(NULL); |
sizeof(struct_variable_partagee))) == NULL) |
} |
{ |
|
(*s_etat_processus).erreur_systeme = d_es_allocation_memoire; |
|
return(d_erreur); |
|
} |
|
|
|
(*(*s_etat_processus).s_liste_variables_partagees).table = |
while((*ptr) != d_code_fin_chaine) |
s_nouvelle_base; |
{ |
|
pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr]; |
|
|
|
if (pointeur < 0) |
|
{ |
|
// Caractère hors de l'alphabet des variables |
|
|
|
pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)); |
|
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
|
return(NULL); |
} |
} |
|
|
position_supprimee = (*(*s_etat_processus) |
if ((*l_variable_courante).noeuds[pointeur] == NULL) |
.s_liste_variables_partagees).position_variable; |
{ |
|
// Le chemin de la variable candidate n'existe pas. |
|
|
liberation(s_etat_processus, (*(*s_etat_processus) |
pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)); |
.s_liste_variables_partagees).table[position_supprimee].objet); |
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
free((*(*s_etat_processus).s_liste_variables_partagees) |
return(NULL); |
.table[position_supprimee].nom); |
} |
|
|
(*(*s_etat_processus).s_liste_variables_partagees).nombre_variables--; |
if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur]) |
|
.mutex_feuille)) != 0) |
|
{ |
|
pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)); |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(NULL); |
|
} |
|
|
for(position_courante = position_supprimee; position_courante < |
if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0) |
(*(*s_etat_processus).s_liste_variables_partagees) |
|
.nombre_variables; position_courante++) |
|
{ |
{ |
(*(*s_etat_processus).s_liste_variables_partagees).table |
(*s_etat_processus).erreur_systeme = d_es_processus; |
[position_courante] = (*(*s_etat_processus) |
return(NULL); |
.s_liste_variables_partagees).table[position_courante + 1]; |
|
} |
} |
|
|
erreur = d_absence_erreur; |
l_variable_courante = (*l_variable_courante).noeuds[pointeur]; |
|
ptr++; |
} |
} |
else |
|
|
if ((*l_variable_courante).feuille != NULL) |
{ |
{ |
erreur = d_erreur; |
// Il existe au moins une variable partagée du nom requis. |
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
|
|
l_element_courant = (*l_variable_courante).feuille; |
|
|
|
while(l_element_courant != NULL) |
|
{ |
|
if ((*(*l_element_courant).variable).origine == 'P') |
|
{ |
|
if (((*(*l_element_courant).variable).variable_partagee.adresse |
|
== position.adresse) && |
|
((*(*l_element_courant).variable).origine == origine)) |
|
{ |
|
if (pthread_mutex_lock(&((*(*l_element_courant).variable) |
|
.mutex)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(NULL); |
|
} |
|
|
|
if (pthread_mutex_unlock(&((*l_variable_courante) |
|
.mutex_feuille)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(NULL); |
|
} |
|
|
|
(*s_etat_processus).pointeur_variable_partagee_courante |
|
= (*l_element_courant).variable; |
|
return(l_element_courant); |
|
} |
|
} |
|
else |
|
{ |
|
if (((*(*l_element_courant).variable).variable_partagee.pointeur |
|
== position.pointeur) && |
|
((*(*l_element_courant).variable).origine == origine)) |
|
{ |
|
if (pthread_mutex_lock(&((*(*l_element_courant).variable) |
|
.mutex)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(NULL); |
|
} |
|
|
|
if (pthread_mutex_unlock(&((*l_variable_courante) |
|
.mutex_feuille)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(NULL); |
|
} |
|
|
|
(*s_etat_processus).pointeur_variable_partagee_courante |
|
= (*l_element_courant).variable; |
|
return(l_element_courant); |
|
} |
|
} |
|
|
|
l_element_courant = (*l_element_courant).suivant; |
|
} |
} |
} |
|
|
return erreur; |
if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(NULL); |
|
} |
|
|
|
(*s_etat_processus).pointeur_variable_statique_courante = NULL; |
|
return(NULL); |
} |
} |
|
|
|
|
/* |
/* |
================================================================================ |
================================================================================ |
Procédure de recherche d'une variable partagee par son nom dans la base |
Routine de retrait d'une variable partagée |
================================================================================ |
================================================================================ |
Entrée : |
Entrée : |
-------------------------------------------------------------------------------- |
-------------------------------------------------------------------------------- |
Sortie : |
Sortie : |
-------------------------------------------------------------------------------- |
-------------------------------------------------------------------------------- |
Effets de bord : néant |
Effets de bords : néant |
================================================================================ |
================================================================================ |
*/ |
*/ |
|
|
logical1 |
logical1 |
recherche_variable_partagee(struct_processus *s_etat_processus, |
retrait_variable_partagee(struct_processus *s_etat_processus, |
unsigned char *nom_variable, union_position_variable position, |
unsigned char *nom_variable, union_position_variable position) |
unsigned char origine) |
|
{ |
{ |
logical1 existence_variable; |
struct_liste_variables_partagees *l_element_a_supprimer; |
|
struct_liste_variables_partagees *l_element_liste_a_supprimer; |
|
|
long difference; |
logical1 erreur; |
long difference_inferieure; |
|
long difference_superieure; |
|
|
|
unsigned long borne_inferieure; |
|
unsigned long borne_superieure; |
|
unsigned long moyenne; |
|
unsigned long nombre_iterations_maximal; |
|
unsigned long ordre_iteration; |
|
|
|
if ((*(*s_etat_processus).s_liste_variables_partagees) |
if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus, |
.nombre_variables == 0) |
nom_variable, position, ((*s_etat_processus) |
|
.mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL) |
{ |
{ |
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0) |
return d_faux; |
{ |
} |
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
ordre_iteration = 0; |
// (*s_etat_processus).pointeur_variable_partagee_courante |
nombre_iterations_maximal = ((unsigned long) |
// pointe sur la variable à éliminer. Cette variable est celle qui |
(log((*(*s_etat_processus).s_liste_variables_partagees) |
// est présente dans l'une des feuilles statiques de l'arbre des |
.nombre_variables) / log(2))) + 2; |
// variables. |
|
|
borne_inferieure = 0; |
l_element_liste_a_supprimer = (*l_element_a_supprimer).reference; |
borne_superieure = (*(*s_etat_processus).s_liste_variables_partagees) |
|
.nombre_variables - 1; |
|
|
|
do |
// Suppression de la liste des variables statiques |
{ |
|
moyenne = (borne_inferieure + borne_superieure) / 2; |
|
ordre_iteration++; |
|
|
|
if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2))) |
if ((*l_element_liste_a_supprimer).precedent != NULL) |
== (borne_inferieure + borne_superieure)) |
|
{ |
{ |
difference = strcmp(nom_variable, |
// L'élément à supprimer n'est pas le premier de la liste. |
(*(*s_etat_processus).s_liste_variables_partagees) |
|
.table[moyenne].nom); |
|
|
|
if (difference != 0) |
(*(*l_element_liste_a_supprimer).precedent).suivant = |
|
(*l_element_liste_a_supprimer).suivant; |
|
|
|
if ((*l_element_liste_a_supprimer).suivant != NULL) |
{ |
{ |
if (difference > 0) |
// Il y a un élément suivant. On le chaîne. |
{ |
(*(*l_element_liste_a_supprimer).suivant).precedent = NULL; |
borne_inferieure = moyenne; |
|
} |
|
else |
|
{ |
|
borne_superieure = moyenne; |
|
} |
|
} |
} |
} |
} |
else |
else |
{ |
{ |
difference_inferieure = strcmp(nom_variable, |
// L'élement est le premier de la liste. S'il y a un élément |
(*(*s_etat_processus).s_liste_variables_partagees).table |
// suivant, on le chaîne. |
[moyenne].nom); |
|
difference_superieure = strcmp(nom_variable, |
|
(*(*s_etat_processus).s_liste_variables_partagees).table |
|
[moyenne + 1].nom); |
|
|
|
if (difference_inferieure == 0) |
if ((*l_element_liste_a_supprimer).suivant != NULL) |
{ |
{ |
difference = 0; |
(*(*l_element_liste_a_supprimer).suivant).precedent = NULL; |
} |
} |
else if (difference_superieure == 0) |
|
{ |
|
difference = 0; |
|
moyenne++; |
|
} |
|
else |
|
{ |
|
difference = difference_inferieure; |
|
|
|
if (difference > 0) |
(*(*s_etat_processus).l_liste_variables_partagees) = |
{ |
(*l_element_liste_a_supprimer).suivant; |
borne_inferieure = moyenne; |
|
} |
|
else |
|
{ |
|
borne_superieure = moyenne; |
|
} |
|
} |
|
} |
} |
} while((difference != 0) && |
|
(ordre_iteration <= nombre_iterations_maximal)); |
|
|
|
if (ordre_iteration > nombre_iterations_maximal) |
free(l_element_liste_a_supprimer); |
{ |
|
existence_variable = d_faux; |
|
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
|
} |
|
else |
|
{ |
|
// Reste à rechercher la variable déclarée à la position 'position'... |
|
|
|
if ((*(*s_etat_processus).s_liste_variables_partagees).table[moyenne] |
// Suppression depuis la feuille statique. Le champ 'precedent' ne sert |
.origine == 'P') |
// pas car la liste est simplement chaînée. |
|
|
|
if ((*l_element_a_supprimer).precedent != NULL) |
{ |
{ |
if (((*(*s_etat_processus).s_liste_variables_partagees) |
// L'élément n'est pas le premier de la liste. |
.table[moyenne].variable_partagee.adresse == |
|
position.adresse) && ((*(*s_etat_processus) |
(*(*l_element_a_supprimer).precedent).suivant = |
.s_liste_variables_partagees).table[moyenne] |
(*l_element_a_supprimer).suivant; |
.origine == origine)) |
|
|
if ((*l_element_a_supprimer).suivant != NULL) |
{ |
{ |
existence_variable = d_vrai; |
(*(*l_element_a_supprimer).suivant).precedent = |
|
(*l_element_a_supprimer).precedent; |
} |
} |
else |
else |
{ |
{ |
existence_variable = d_faux; |
(*(*l_element_a_supprimer).precedent).suivant = NULL; |
} |
} |
} |
} |
else |
else |
{ |
{ |
if (((*(*s_etat_processus).s_liste_variables_partagees) |
// L'élément est le premier de la liste. |
.table[moyenne].variable_partagee.pointeur == |
|
position.pointeur) && ((*(*s_etat_processus) |
if ((*l_element_a_supprimer).suivant != NULL) |
.s_liste_variables_partagees).table[moyenne] |
|
.origine == origine)) |
|
{ |
|
existence_variable = d_vrai; |
|
} |
|
else |
|
{ |
{ |
existence_variable = d_faux; |
(*(*l_element_a_supprimer).suivant).precedent = NULL; |
} |
} |
|
|
|
(*(*l_element_a_supprimer).feuille).feuille |
|
= (*l_element_a_supprimer).suivant; |
} |
} |
|
|
if (existence_variable == d_faux) |
liberation(s_etat_processus, (*(*l_element_a_supprimer).variable) |
|
.objet); |
|
free((*(*l_element_a_supprimer).variable).nom); |
|
pthread_mutex_unlock(&((*(*l_element_a_supprimer).variable).mutex)); |
|
pthread_mutex_destroy(&((*(*l_element_a_supprimer).variable).mutex)); |
|
free((*l_element_a_supprimer).variable); |
|
free(l_element_a_supprimer); |
|
|
|
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
{ |
{ |
// On rembobine. |
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
if (moyenne > 0) |
erreur = d_absence_erreur; |
{ |
} |
while(strcmp(nom_variable, (*(*s_etat_processus) |
else |
.s_liste_variables_partagees).table[moyenne - 1].nom) |
{ |
== 0) |
erreur = d_erreur; |
{ |
(*s_etat_processus).erreur_systeme = d_es_variable_introuvable; |
moyenne--; |
} |
|
|
|
return(erreur); |
|
} |
|
|
if (moyenne == 0) |
|
{ |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Un petit test pour voir si le premier élément du tableau |
/* |
// peut correspondre au critère de recherche. |
================================================================================ |
|
Routine de retrait des variables partagées |
|
================================================================================ |
|
Entrée : |
|
-------------------------------------------------------------------------------- |
|
Sortie : |
|
-------------------------------------------------------------------------------- |
|
Effets de bords : néant |
|
================================================================================ |
|
*/ |
|
|
|
// Cette routine libère toutes les variables partagées de niveau non |
|
// nul, donc attachées à une expression et non un programme. |
|
|
existence_variable = d_faux; |
logical1 |
|
retrait_variables_partagees_locales(struct_processus *s_etat_processus) |
|
{ |
|
struct_liste_variables_partagees *l_element_courant; |
|
struct_liste_variables_partagees *l_element_suivant; |
|
|
|
unsigned char registre_mode_execution; |
|
|
|
if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return(d_erreur); |
|
} |
|
|
if (strcmp((*(*s_etat_processus).s_liste_variables_partagees).table |
registre_mode_execution = (*s_etat_processus).mode_execution_programme; |
[moyenne].nom, nom_variable) == 0) |
l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees); |
|
|
|
while(l_element_courant != NULL) |
|
{ |
|
l_element_suivant = (*l_element_courant).suivant; |
|
|
|
(*s_etat_processus).mode_execution_programme = |
|
((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N'; |
|
|
|
if (((*(*l_element_courant).variable).niveau > 0) && |
|
((*l_element_courant).pid == getpid()) && |
|
(pthread_equal((*l_element_courant).tid, pthread_self()) != 0)) |
|
{ |
|
if (retrait_variable_partagee(s_etat_processus, |
|
(*(*l_element_courant).variable).nom, |
|
(*(*l_element_courant).variable).variable_partagee) |
|
== d_erreur) |
{ |
{ |
if ((*(*s_etat_processus).s_liste_variables_partagees).table |
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
[moyenne].origine == 'P') |
|
{ |
{ |
if (((*(*s_etat_processus).s_liste_variables_partagees) |
(*s_etat_processus).erreur_systeme = d_es_processus; |
.table[moyenne].variable_partagee.adresse |
return(d_erreur); |
== position.adresse) && |
|
((*(*s_etat_processus).s_liste_variables_partagees) |
|
.table[moyenne].origine == origine)) |
|
{ |
|
existence_variable = d_vrai; |
|
} |
|
} |
|
else |
|
{ |
|
if (((*(*s_etat_processus).s_liste_variables_partagees) |
|
.table[moyenne].variable_partagee.pointeur |
|
== position.pointeur) && |
|
((*(*s_etat_processus).s_liste_variables_partagees) |
|
.table[moyenne].origine == origine)) |
|
{ |
|
existence_variable = d_vrai; |
|
} |
|
} |
} |
|
|
|
(*s_etat_processus).mode_execution_programme = |
|
registre_mode_execution; |
|
return(d_erreur); |
} |
} |
|
} |
|
|
// Puis on balaye dans le sens croissant. |
l_element_courant = l_element_suivant; |
|
} |
|
|
if (((moyenne + 1) < (*(*s_etat_processus) |
(*s_etat_processus).mode_execution_programme = registre_mode_execution; |
.s_liste_variables_partagees).nombre_variables) |
|
&& (existence_variable == d_faux)) |
|
{ |
|
while(strcmp((*(*s_etat_processus) |
|
.s_liste_variables_partagees).table[moyenne + 1].nom, |
|
nom_variable) == 0) |
|
{ |
|
moyenne++; |
|
|
|
if ((*(*s_etat_processus).s_liste_variables_partagees) |
if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0) |
.table[moyenne].origine == 'P') |
{ |
{ |
(*s_etat_processus).erreur_systeme = d_es_processus; |
if (((*(*s_etat_processus).s_liste_variables_partagees) |
return(d_erreur); |
.table[moyenne].variable_partagee.adresse == |
} |
position.adresse) && ((*(*s_etat_processus) |
|
.s_liste_variables_partagees) |
|
.table[moyenne].origine == origine)) |
|
{ |
|
existence_variable = d_vrai; |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
if (((*(*s_etat_processus).s_liste_variables_partagees) |
|
.table[moyenne].variable_partagee.pointeur == |
|
position.pointeur) && ((*(*s_etat_processus) |
|
.s_liste_variables_partagees) |
|
.table[moyenne].origine == origine)) |
|
{ |
|
existence_variable = d_vrai; |
|
break; |
|
} |
|
} |
|
|
|
if ((moyenne + 1) >= (*(*s_etat_processus) |
return(d_absence_erreur); |
.s_liste_variables_partagees).nombre_variables) |
} |
{ |
|
break; |
|
} |
/* |
} |
================================================================================ |
} |
Routine de libération de l'arbre des variables partagées |
} |
================================================================================ |
|
Entrée : |
|
-------------------------------------------------------------------------------- |
|
Sortie : |
|
-------------------------------------------------------------------------------- |
|
Effets de bords : positionne le mutex sur la variable partagée |
|
================================================================================ |
|
*/ |
|
|
|
void |
|
liberation_arbre_variables_partagees(struct_processus *s_etat_processus, |
|
struct_arbre_variables_partagees *arbre) |
|
{ |
|
int i; |
|
|
|
struct_liste_variables_partagees *l_element_partage_courant; |
|
struct_liste_variables_partagees *l_element_partage_suivant; |
|
|
|
// Libération de l'arbre des variables. Le contenu des variables n'est |
|
// pas détruit par cette opération, il sera détruit lors de la libération |
|
// de la liste des variables par niveau. |
|
|
(*(*s_etat_processus).s_liste_variables_partagees).position_variable |
if (arbre == NULL) |
= moyenne; |
{ |
|
return; |
} |
} |
|
|
/* |
if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0) |
* Si la variable partagée n'existe pas, elle a été rendue privée par un |
{ |
* thread concurrent. Il faut donc l'enlever de la table des variables |
(*s_etat_processus).erreur_systeme = d_es_processus; |
* du thread courant. |
return; |
*/ |
} |
|
|
if (existence_variable == d_faux) |
l_element_partage_courant = (*arbre).feuille; |
|
|
|
while(l_element_partage_courant != NULL) |
{ |
{ |
if (retrait_variable(s_etat_processus, nom_variable, 'L') == d_faux) |
l_element_partage_suivant = (*l_element_partage_courant).suivant; |
|
|
|
if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable) |
|
.mutex)) != 0) |
{ |
{ |
return d_faux; |
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return; |
} |
} |
|
|
|
free((*(*l_element_partage_courant).variable).nom); |
|
liberation(s_etat_processus, (*(*l_element_partage_courant) |
|
.variable).objet); |
|
free((*l_element_partage_courant).variable); |
|
|
|
if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable) |
|
.mutex)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return; |
|
} |
|
|
|
if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable) |
|
.mutex)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return; |
|
} |
|
|
|
free(l_element_partage_courant); |
|
|
|
l_element_partage_courant = l_element_partage_suivant; |
|
} |
|
|
|
for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++) |
|
{ |
|
if ((*arbre).noeuds[i] != NULL) |
|
{ |
|
liberation_arbre_variables_partagees(s_etat_processus, |
|
(*arbre).noeuds[i]); |
|
(*arbre).noeuds[i] = NULL; |
|
} |
|
} |
|
|
|
liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds); |
|
liberation_noeud_partage(s_etat_processus, arbre); |
|
|
|
if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return; |
|
} |
|
|
|
if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0) |
|
{ |
|
(*s_etat_processus).erreur_systeme = d_es_processus; |
|
return; |
} |
} |
|
|
return existence_variable; |
arbre = NULL; |
|
return; |
} |
} |
|
|
// vim: ts=4 |
// vim: ts=4 |