/* ================================================================================ 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" /* ================================================================================ Fonction 'protect' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_protect(struct_processus *s_etat_processus) { struct_liste_chainee *l_element_courant; struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PROTECT "); if ((*s_etat_processus).langue == 'F') { printf("(verrouille une variable)\n\n"); } else { printf("(lock a variable)\n\n"); } printf(" 1: %s, %s\n", d_NOM, d_LST); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet).type == NOM) { if (recherche_variable(s_etat_processus, ((*((struct_nom *) (*s_objet).objet)).nom)) == d_faux) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } (*(*s_etat_processus).pointeur_variable_courante) .variable_verrouillee = d_vrai; } else if ((*s_objet).type == LST) { l_element_courant = (struct_liste_chainee *) (*s_objet).objet; while(l_element_courant != NULL) { if ((*(*l_element_courant).donnee).type != NOM) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_nom_invalide; return; } if (recherche_variable(s_etat_processus, (*((struct_nom *) (*(*l_element_courant).donnee).objet)).nom) == d_faux) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } (*(*s_etat_processus).pointeur_variable_courante) .variable_verrouillee = d_vrai; l_element_courant = (*l_element_courant).suivant; } } else { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet); return; } /* ================================================================================ Fonction 'parameter' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_parameter(struct_processus *s_etat_processus) { struct_liste_chainee *l_element_courant; struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PARAMETER "); if ((*s_etat_processus).langue == 'F') { printf("(verrouille une variable globale)\n\n"); } else { printf("(lock a global variable)\n\n"); } printf(" 1: %s, %s\n", d_NOM, d_LST); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet).type == NOM) { if (recherche_variable_globale(s_etat_processus, ((*((struct_nom *) (*s_objet).objet)).nom)) == d_faux) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } (*(*s_etat_processus).pointeur_variable_courante) .variable_verrouillee = d_vrai; } else if ((*s_objet).type == LST) { l_element_courant = (struct_liste_chainee *) (*s_objet).objet; while(l_element_courant != NULL) { if ((*(*l_element_courant).donnee).type != NOM) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_nom_invalide; return; } if (recherche_variable_globale(s_etat_processus, (*((struct_nom *) (*(*l_element_courant).donnee).objet)).nom) == d_faux) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } (*(*s_etat_processus).pointeur_variable_courante) .variable_verrouillee = d_vrai; l_element_courant = (*l_element_courant).suivant; } } else { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet); return; } /* ================================================================================ Fonction 'pshcntxt' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_pshcntxt(struct_processus *s_etat_processus) { struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PSHCNTXT "); if ((*s_etat_processus).langue == 'F') { printf("(sauvegarde de contexte)\n\n"); printf(" Aucun argument\n"); } else { printf("(pushes context)\n\n"); printf(" No argument\n"); } return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((s_objet = allocation(s_etat_processus, LST)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*s_objet).objet = (*s_etat_processus).l_base_pile; if (empilement(s_etat_processus, &((*s_etat_processus). l_base_pile_contextes), s_objet) == d_erreur) { return; } if ((s_objet = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((integer8 *) (*s_objet).objet)) = (*s_etat_processus) .hauteur_pile_operationnelle; if (empilement(s_etat_processus, &((*s_etat_processus) .l_base_pile_taille_contextes), s_objet) == d_erreur) { return; } /* * Vidage de la pile opérationnelle */ (*s_etat_processus).l_base_pile = NULL; (*s_etat_processus).hauteur_pile_operationnelle = 0; return; } /* ================================================================================ Fonction 'pulcntxt' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_pulcntxt(struct_processus *s_etat_processus) { struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PULCNTXT "); if ((*s_etat_processus).langue == 'F') { printf("(restauration de contexte)\n\n"); printf(" Aucun argument\n"); } else { printf("(pulls context)\n\n"); printf(" No argument\n"); } return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if (((*s_etat_processus).l_base_pile_contextes == NULL) || ((*s_etat_processus).l_base_pile_taille_contextes == NULL)) { (*s_etat_processus).erreur_execution = d_ex_contexte; return; } instruction_clear(s_etat_processus); if (depilement(s_etat_processus, &((*s_etat_processus) .l_base_pile_contextes), &s_objet) == d_erreur) { return; } if ((*s_objet).type != LST) { (*s_etat_processus).erreur_systeme = d_es_contexte; return; } (*s_etat_processus).l_base_pile = (*s_objet).objet; BUG((*s_objet).nombre_occurrences != 1, printf("(*s_objet).nombre_occurrences=%ld\n", (*s_objet).nombre_occurrences)); free(s_objet); if (depilement(s_etat_processus, &((*s_etat_processus) .l_base_pile_taille_contextes), &s_objet) == d_erreur) { return; } if ((*s_objet).type != INT) { (*s_etat_processus).erreur_systeme = d_es_contexte; return; } if ((*((integer8 *) (*s_objet).objet)) < 0) { (*s_etat_processus).erreur_systeme = d_es_contexte; return; } (*s_etat_processus).hauteur_pile_operationnelle = (*((integer8 *) (*s_objet).objet)); liberation(s_etat_processus, s_objet); return; } /* ================================================================================ Fonction 'peek' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_peek(struct_processus *s_etat_processus) { sig_atomic_t registre; struct_objet *s_objet; struct_objet *s_objet_drapeau; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PEEK "); if ((*s_etat_processus).langue == 'F') { printf("(réception de données d'un processus père)\n\n"); } else { printf("(data reception from parent process)\n\n"); } printf("-> 1: %s (0)\n\n", d_INT); printf("-> 2: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN); printf(" 1: %s (-1)\n", d_INT); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((*s_etat_processus).presence_pipes == d_faux) { (*s_etat_processus).erreur_execution = d_ex_absence_processus_pere; return; } if ((s_objet_drapeau = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((*s_etat_processus).nombre_objets_injectes > 0) { registre = (*s_etat_processus).var_volatile_traitement_retarde_stop; (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, "Interprocess or interthread " "communications (PEEK)"); if ((*s_etat_processus).erreur_systeme != d_es) { return; } } if ((s_objet = lecture_pipe(s_etat_processus, (*s_etat_processus).pipe_injections)) == NULL) { if (registre == 0) { if ((*s_etat_processus).var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } return; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } if (registre == 0) { if ((*s_etat_processus).var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre; } (*s_etat_processus).nombre_objets_injectes--; if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet) == d_erreur) { return; } (*((integer8 *) (*s_objet_drapeau).objet)) = -1; } else { (*((integer8 *) (*s_objet_drapeau).objet)) = 0; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_drapeau) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'poke' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_poke(struct_processus *s_etat_processus) { sig_atomic_t registre_stop; ssize_t longueur_ecriture; struct sigaction action; struct sigaction registre; struct_liste_chainee *l_element_courant; struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n POKE "); if ((*s_etat_processus).langue == 'F') { printf("(envoi d'une donnée à un processus fils)\n\n"); } else { printf("(send data to child process)\n\n"); } printf(" 2: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_TAB); printf(" 1: %s\n", d_PRC); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 2) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_1) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument_1).type == PRC) { /* * Vérification du type de la donnée transmise */ if (((*s_objet_argument_2).type != INT) && ((*s_objet_argument_2).type != REL) && ((*s_objet_argument_2).type != CPL) && ((*s_objet_argument_2).type != VIN) && ((*s_objet_argument_2).type != VRL) && ((*s_objet_argument_2).type != VCX) && ((*s_objet_argument_2).type != MIN) && ((*s_objet_argument_2).type != MRL) && ((*s_objet_argument_2).type != MCX) && ((*s_objet_argument_2).type != BIN) && ((*s_objet_argument_2).type != NOM) && ((*s_objet_argument_2).type != CHN) && ((*s_objet_argument_2).type != LST) && ((*s_objet_argument_2).type != ALG) && ((*s_objet_argument_2).type != RPN) && ((*s_objet_argument_2).type != TBL)) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } if (pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; while(l_element_courant != NULL) { if ((*(*((struct_processus_fils *) (*s_objet_argument_1).objet)) .thread).processus_detache == d_vrai) { if ((*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache == d_faux) { l_element_courant = (*l_element_courant).suivant; continue; } if ((*(*((struct_processus_fils *) (*s_objet_argument_1).objet)) .thread).pid == (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).pid) { // Envoi des données // Attention : si le processus n'existe plus, il n'y a plus // de lecteur et on peut se prendre un SIGPIPE dans la // figure ! action.sa_handler = SIG_IGN; action.sa_flags = 0; # ifndef SEMAPHORES_NOMMES if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) # else if (sem_post((*s_etat_processus).semaphore_fork) != 0) # endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pthread_mutex_lock(&mutex_sigaction) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (sigaction(SIGPIPE, &action, ®istre) != 0) { pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); (*s_etat_processus).erreur_systeme = d_es_signal; return; } // Validation des données. On envoie un signal pour // débloquer les instructions de type WF* pour les // lectures bloquantes. if (envoi_signal_processus((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).pid, rpl_siginject, d_faux) != 0) { // Le processus fils peut s'être terminé. break; } registre_stop = (*s_etat_processus) .var_volatile_traitement_retarde_stop; (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, "Interprocess communications (POKE)"); if ((*s_etat_processus).erreur_systeme != d_es) { pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); return; } } while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .pipe_nombre_injections[1], "-", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); if (registre_stop == 0) { if ((*s_etat_processus) .var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus) .var_volatile_requete_arret = -1; } (*s_etat_processus) .var_volatile_traitement_retarde_stop = registre_stop; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } if (sigaction(SIGPIPE, ®istre, NULL) != 0) { pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_signal; return; } return; } } if (ecriture_pipe(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .pipe_injections[1], s_objet_argument_2) == d_erreur) { // Le processus fils peut s'être terminé. if ((*s_etat_processus).erreur_systeme != d_es) { (*s_etat_processus).erreur_systeme = d_es; } } if (registre_stop == 0) { if ((*s_etat_processus) .var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre_stop; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } if (sigaction(SIGPIPE, ®istre, NULL) != 0) { pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); (*s_etat_processus).erreur_systeme = d_es_signal; return; } if (pthread_mutex_unlock(&mutex_sigaction) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } break; } } else { if ((*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache == d_vrai) { l_element_courant = (*l_element_courant).suivant; continue; } if (((pthread_equal((*(*((struct_processus_fils *) (*s_objet_argument_1).objet)).thread).tid, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).tid) != 0)) && ((*(*((struct_processus_fils *) (*s_objet_argument_1).objet)).thread).pid == (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).pid)) { // Envoi des données // Attention : si le processus n'existe plus, il n'y a plus // de lecteur et on peut se prendre un SIGPIPE dans la // figure ! # ifndef SEMAPHORES_NOMMES if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) # else if (sem_post((*s_etat_processus).semaphore_fork) != 0) # endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pthread_mutex_lock(&mutex_sigaction) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } (*s_etat_processus).erreur_systeme = d_es_processus; return; } action.sa_handler = SIG_IGN; action.sa_flags = 0; if (sigaction(SIGPIPE, &action, ®istre) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); (*s_etat_processus).erreur_systeme = d_es_signal; return; } // Validation des données. On envoie un signal pour // débloquer les instructions de type WF* pour les // lectures bloquantes. if (pthread_mutex_lock(&((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .mutex)) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_processus; return; } if ((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .thread_actif == d_vrai) { if (envoi_signal_thread(NULL, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .tid, rpl_siginject) != 0) { // Le processus fils peut s'être terminé. if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_processus; return; } break; } } else { if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_processus; return; } break; } if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .mutex)) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_processus; return; } registre_stop = (*s_etat_processus) .var_volatile_traitement_retarde_stop; (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, "Interthread communications (POKE)"); if ((*s_etat_processus).erreur_systeme != d_es) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); return; } } while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .pipe_nombre_injections[1], "-", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); if (registre_stop == 0) { if ((*s_etat_processus) .var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus) .var_volatile_requete_arret = -1; } (*s_etat_processus) .var_volatile_traitement_retarde_stop = registre_stop; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } if (sigaction(SIGPIPE, ®istre, NULL) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_signal; return; } # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); return; } } if (ecriture_pipe(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .pipe_injections[1], s_objet_argument_2) == d_erreur) { // Le processus fils peut s'être terminé. if ((*s_etat_processus).erreur_systeme != d_es) { (*s_etat_processus).erreur_systeme = d_es; } } if (registre_stop == 0) { if ((*s_etat_processus) .var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre_stop; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } if (sigaction(SIGPIPE, ®istre, NULL) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } pthread_mutex_unlock(&mutex_sigaction); pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)); (*s_etat_processus).erreur_systeme = d_es_signal; return; } if (pthread_mutex_unlock(&mutex_sigaction) != 0) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus) .semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus) .semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } (*s_etat_processus).erreur_systeme = d_es_processus; return; } # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } break; } } l_element_courant = (*l_element_courant).suivant; } if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (l_element_courant == NULL) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_processus; return; } } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); return; } /* ================================================================================ Fonction 'private' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_private(struct_processus *s_etat_processus) { struct_liste_chainee *l_element_courant; struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PRIVATE "); if ((*s_etat_processus).langue == 'F') { printf("(rend privée une variable partagée)\n\n"); } else { printf("(switch a shared variable to private one)\n\n"); } printf(" 1: %s, %s\n", d_NOM, d_LST); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet).type == NOM) { if (recherche_variable(s_etat_processus, ((*((struct_nom *) (*s_objet).objet)).nom)) == d_faux) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } if (recherche_variable_partagee(s_etat_processus, ((*((struct_nom *) (*s_objet).objet)).nom), (*(*s_etat_processus) .pointeur_variable_courante).variable_partagee, (*(*s_etat_processus).pointeur_variable_courante).origine) == NULL) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; return; } (*(*s_etat_processus).pointeur_variable_courante).objet = (*(*s_etat_processus).pointeur_variable_partagee_courante) .objet; (*(*s_etat_processus).pointeur_variable_partagee_courante).objet = NULL; if (retrait_variable_partagee(s_etat_processus, (*((struct_nom *) (*s_objet).objet)).nom, (*(*s_etat_processus).pointeur_variable_courante) .variable_partagee) == d_erreur) { liberation(s_etat_processus, s_objet); return; } if ((*(*s_etat_processus).pointeur_variable_courante).origine == 'P') { (*(*s_etat_processus).pointeur_variable_courante) .variable_partagee.adresse = 0; } else { (*(*s_etat_processus).pointeur_variable_courante) .variable_partagee.pointeur = NULL; } } else if ((*s_objet).type == LST) { l_element_courant = (struct_liste_chainee *) (*s_objet).objet; while(l_element_courant != NULL) { if ((*(*l_element_courant).donnee).type != NOM) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_nom_invalide; return; } if (recherche_variable(s_etat_processus, ((*((struct_nom *) (*s_objet).objet)).nom)) == d_faux) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } if (recherche_variable_partagee(s_etat_processus, ((*((struct_nom *) (*s_objet).objet)).nom), (*(*s_etat_processus) .pointeur_variable_courante).variable_partagee, (*(*s_etat_processus).pointeur_variable_courante).origine) == NULL) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex_variable_non_definie; return; } (*(*s_etat_processus).pointeur_variable_courante).objet = (*(*s_etat_processus).pointeur_variable_partagee_courante) .objet; (*(*s_etat_processus).pointeur_variable_partagee_courante).objet = NULL; if ((*(*s_etat_processus).pointeur_variable_courante).origine == 'P') { (*(*s_etat_processus).pointeur_variable_courante) .variable_partagee.adresse = 0; } else { (*(*s_etat_processus).pointeur_variable_courante) .variable_partagee.pointeur = NULL; } if (retrait_variable_partagee(s_etat_processus, (*((struct_nom *) (*s_objet).objet)).nom, (*(*s_etat_processus).pointeur_variable_courante) .variable_statique) == d_erreur) { liberation(s_etat_processus, s_objet); return; } l_element_courant = (*l_element_courant).suivant; } } else { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet); return; } /* ================================================================================ Fonction 'pshprfl' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_pshprfl(struct_processus *s_etat_processus) { struct_objet *s_objet_argument; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PSHPRFL "); if ((*s_etat_processus).langue == 'F') { printf("(empilement d'un point de profilage)\n\n"); } else { printf("(push profile data)\n\n"); } printf(" 1: %s\n", d_CHN); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == CHN) { if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, (unsigned char *) (*s_objet_argument).objet); } } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); return; } /* ================================================================================ Fonction 'pulprfl' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_pulprfl(struct_processus *s_etat_processus) { (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PULPRFL "); if ((*s_etat_processus).langue == 'F') { printf("(dépilement d'un point de profilage)\n\n"); printf(" Aucun argument\n"); } else { printf("(pull profile data)\n\n"); printf(" No argument\n"); } return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } return; } /* ================================================================================ Fonction 'plot' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_plot(struct_processus *s_etat_processus) { (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PLOT "); if ((*s_etat_processus).langue == 'F') { printf("(affiche les données graphiques mémorisées)\n\n"); printf(" Aucun argument\n"); } else { printf("(plot buffered graphic)\n\n"); printf(" No argument\n"); } return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((*s_etat_processus).fichiers_graphiques != NULL) { appel_gnuplot(s_etat_processus, 'N'); } (*s_etat_processus).mise_a_jour_trace_requise = d_faux; return; } /* ================================================================================ Fonction 'procid' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_procid(struct_processus *s_etat_processus) { pthread_mutexattr_t attributs_mutex; struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n PROCID "); if ((*s_etat_processus).langue == 'F') { printf("(identifiant du processus)\n\n"); } else { printf("(process identifier)\n\n"); } printf("-> 1: %s\n", d_PRC); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((s_objet = allocation(s_etat_processus, PRC)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*((struct_processus_fils *) (*s_objet).objet)).thread = malloc(sizeof(struct_descripteur_thread))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .nombre_references = 1; (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .pid = getpid(); (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .tid = pthread_self(); (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .processus_detache = (*s_etat_processus).processus_detache; (*(*((struct_processus_fils *) (*s_objet).objet)).thread) .argument = NULL; pthread_mutexattr_init(&attributs_mutex); pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); pthread_mutexattr_init(&attributs_mutex); pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex_nombre_references), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet) == d_erreur) { return; } return; } // vim: ts=4