/* ================================================================================ RPL/2 (R) version 4.0.16 Copyright (C) 1989-2010 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 de surveillance d'un processus fils. Elle tourne dans un thread séparé et ferme les descripteurs lors de la mort du fils. ================================================================================ Entrées : pointeur sur une structure -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void * surveillance_processus(void *argument) { int iostat; int status; integer8 nombre_donnees; logical1 drapeau; logical1 drapeau_fin; logical1 drapeau_fin_scrutation; logical1 drapeau_interruptions_traitees; logical1 drapeau_objets_traites; pid_t pid; pid_t pid_candidat; pthread_t tid_candidat; sigset_t masque; ssize_t longueur_ecriture; struct_descripteur_thread *s_argument_thread; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_precedent; struct_processus *s_etat_processus; struct timespec attente; unsigned char caractere; unsigned int tampon_erreur; sigemptyset(&masque); sigaddset(&masque, SIGINJECT); sigaddset(&masque, SIGFSTOP); sigaddset(&masque, SIGFABORT); sigaddset(&masque, SIGURG); sigaddset(&masque, SIGALRM); sigaddset(&masque, SIGCONT); sigaddset(&masque, SIGINT); pthread_sigmask(SIG_BLOCK, &masque, NULL); s_argument_thread = argument; s_etat_processus = (*s_argument_thread).s_etat_processus; insertion_thread_surveillance(s_etat_processus, s_argument_thread); attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; status = 0; drapeau_interruptions_traitees = d_faux; drapeau_objets_traites = d_faux; if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Lancement du thread de surveillance du" " processus %d\n", (int) getpid(), (int) (*s_argument_thread).pid); } else { printf("[%d] Start monitoring of process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); } } else { if ((*s_etat_processus).langue == 'F') { printf("[%d] Lancement du thread de surveillance du" " thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); } else { printf("[%d] Start monitoring of thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); } } fflush(stdout); } /* * On attend une donnée fictive pour être sûr que le processus fils * est bien démarré. */ while(read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_objets_attente[0], &caractere, sizeof(caractere)) == 0) { if ((*s_etat_processus).var_volatile_requete_arret != 0) { drapeau_objets_traites = d_vrai; drapeau_interruptions_traitees = d_vrai; } nanosleep(&attente, NULL); } do { if ((*s_argument_thread).processus_detache == d_vrai) { /* * Le processus est un processus détaché. */ // Scrutation de l'envoi de données par le fils. pid_candidat = 0; if (drapeau_objets_traites == d_vrai) { nanosleep(&attente, NULL); } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_objets_attente[0], &pid_candidat, sizeof(pid_candidat))) == 0) { // Rien dans le pipe nanosleep(&attente, NULL); } else if (iostat != sizeof(pid_candidat)) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { // Un pid est dans le pipe. On vérifie que les deux pids // correspondent. if (pid_candidat == -2) { drapeau_objets_traites = d_vrai; } else if (pid_candidat == -1) { } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_objets_attente[0], &pid_candidat, sizeof(pid_candidat))) == sizeof(pid_candidat)) { if ((*s_argument_thread).pid != pid_candidat) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; BUG(1, printf("Spurious process identifier")); } // Un objet supplémentaire est dans le pipe correspondant // au processus surveillé par ce thread. if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; while(l_element_courant != NULL) { 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 *) (*(*l_element_courant).donnee).objet)) .thread).pid == pid_candidat) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Données en provenance " "du processus %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Data from process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).pipe_acquittement[1], "-", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { (*s_etat_processus) .erreur_systeme_processus_fils = d_es_processus; } } if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Données acquittées " "en provenance du " "processus %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Data acknowklegment " "from process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } break; } l_element_courant = (*l_element_courant).suivant; } BUG(l_element_courant == NULL, printf("Process or thread not found")); if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } pthread_kill((*s_argument_thread).thread_pere, SIGINJECT); } } else { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } // Scrutation de l'envoi d'interruptions par le fils. if (drapeau_interruptions_traitees == d_vrai) { nanosleep(&attente, NULL); } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_interruptions_attente[0], &pid_candidat, sizeof(pid_candidat))) == 0) { // Rien dans le pipe nanosleep(&attente, NULL); } else if (iostat != sizeof(pid_candidat)) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { // Un pid est dans le pipe. On vérifie que les deux pids // correspondent. if (pid_candidat == -2) { drapeau_interruptions_traitees = d_vrai; } else if (pid_candidat == -1) { } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_interruptions_attente [0], &pid_candidat, sizeof(pid_candidat))) == sizeof(pid_candidat)) { if ((*s_argument_thread).pid != pid_candidat) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; BUG(1, printf("Spurious interrupt")); } // Une interruption supplémentaire est dans le pipe // correspondant au processus surveillé par ce thread. if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; while(l_element_courant != NULL) { 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 *) (*(*l_element_courant).donnee).objet)) .thread).pid == pid_candidat) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_traitement_interruption) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Interrution logicielle " "en provenance du processus " "%d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Software interrupt " "from process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee) .objet)).thread) .nombre_interruptions_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*s_etat_processus) .nombre_interruptions_non_affectees++; while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).pipe_acquittement[1], "-", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { (*s_etat_processus) .erreur_systeme_processus_fils = d_es_processus; } } if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_traitement_interruption) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Interruption logicielle " "acquittée en provenance " "du processus %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Software interrupt " "acknowklegment from " "process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } break; } l_element_courant = (*l_element_courant).suivant; } BUG(l_element_courant == NULL, printf("Process or thread not found")); if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } pthread_kill((*s_argument_thread).thread_pere, SIGINJECT); } } else { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } if ((pid = waitpid((*s_argument_thread).pid, &status, WNOHANG)) < 0) { break; } drapeau_fin_scrutation = (!WIFEXITED(status)) || (!WIFSIGNALED(status)) || (pid == 0); if (WIFEXITED(status)) { if (WEXITSTATUS(status) == (0xFF & EXIT_FAILURE)) { (*s_etat_processus).erreur_systeme = d_es_processus; } } } else { /* * Le processus n'est pas détaché. */ // Scrutation de l'envoi de données par le fils. tid_candidat = (pthread_t) 0; if (drapeau_objets_traites == d_vrai) { nanosleep(&attente, NULL); } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_objets_attente[0], &tid_candidat, sizeof(tid_candidat))) == 0) { // Rien dans le pipe nanosleep(&attente, NULL); } else if (iostat != sizeof(tid_candidat)) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { // Un pid est dans le pipe. On vérifie que les deux pids // correspondent. if (tid_candidat == (pthread_t) -2) { drapeau_objets_traites = d_vrai; } else if (tid_candidat == (pthread_t) -1) { } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_objets_attente[0], &tid_candidat, sizeof(tid_candidat))) == sizeof(tid_candidat)) { if (pthread_equal((*s_argument_thread).tid, tid_candidat) == 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; BUG(1, printf("Spurious thread identifier")); } // Un objet supplémentaire est dans le pipe correspondant // au processus surveillé par ce thread. if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; while(l_element_courant != NULL) { 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 *) (*(*l_element_courant).donnee).objet)) .thread).tid, tid_candidat) != 0) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Données en provenance " "du thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Data from thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).pipe_acquittement[1], "-", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { (*s_etat_processus) .erreur_systeme_processus_fils = d_es_processus; } } if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Données acquittées " "en provenance du thread " "%llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Data acknowklegment " "from thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } break; } l_element_courant = (*l_element_courant).suivant; } BUG(l_element_courant == NULL, printf("Process or thread not found\n")); if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } } else { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } // Scrutation de l'envoi d'interruptions par le fils. if (drapeau_interruptions_traitees == d_vrai) { nanosleep(&attente, NULL); } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_interruptions_attente[0], &tid_candidat, sizeof(tid_candidat))) == 0) { // Rien dans le pipe nanosleep(&attente, NULL); } else if (iostat != sizeof(tid_candidat)) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { // Un pid est dans le pipe. On vérifie que les deux pids // correspondent. if (tid_candidat == (pthread_t) -2) { drapeau_interruptions_traitees = d_vrai; } else if (tid_candidat == (pthread_t) -1) { } else if ((iostat = read_atomic(s_etat_processus, (*s_argument_thread).pipe_nombre_interruptions_attente [0], &tid_candidat, sizeof(tid_candidat))) == sizeof(tid_candidat)) { if (pthread_equal((*s_argument_thread).tid, tid_candidat) == 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; BUG(1, printf("Spurious interrupt")); } // Une interruption supplémentaire est dans le pipe // correspondant au processus surveillé par ce thread. if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; while(l_element_courant != NULL) { 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 *) (*(*l_element_courant).donnee).objet)) .thread).tid, tid_candidat) != 0) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Interrution logicielle " "en provenance du thread " "%llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Software interrupt " "from thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee) .objet)).thread) .nombre_interruptions_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*s_etat_processus) .nombre_interruptions_non_affectees++; while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).pipe_acquittement[1], "-", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { (*s_etat_processus) .erreur_systeme_processus_fils = d_es_processus; } } if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_traitement_interruption) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Interruption logicielle " "acquittée en provenance " "du thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Software interrupt " "acknowklegment from " "thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } break; } l_element_courant = (*l_element_courant).suivant; } BUG(l_element_courant == NULL, printf("Process or thread not found")); if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } } else { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } if ((*s_argument_thread).thread_actif == d_faux) { if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } pthread_join((*s_argument_thread).tid, NULL); drapeau_fin_scrutation = (0 != 0); } else { if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } drapeau_fin_scrutation = (0 == 0); } } } while(drapeau_fin_scrutation); /* * Le processus fils est terminé. On s'assure qu'il ne * reste plus rien dans les tuyaux... */ if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Surveillance des tuyaux du processus %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Check remaining pipes of process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } else { if ((*s_etat_processus).langue == 'F') { printf("[%d] Surveillance des tuyaux du thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Check remaining pipes of thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } } l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; if (drapeau_objets_traites == d_faux) { if ((*s_argument_thread).processus_detache == d_vrai) { while(l_element_courant != NULL) { 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 *) (*(*l_element_courant) .donnee).objet)).thread).pid == (*s_argument_thread).pid) { while(read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_objets_attente[0], &pid_candidat, sizeof(pid_candidat)) == sizeof(pid_candidat)) { /* * -1 est renvoyé par l'instruction SWI */ if (pid_candidat == -2) { break; } else if (pid_candidat == -1) { } else if (read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_objets_attente[0], &pid_candidat, sizeof(pid_candidat)) == sizeof(pid_candidat)) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Données en provenance du " "processus %d (processus " "arrêté)\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Data from process %d " "(processus stopped)\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } } } break; } l_element_courant = (*l_element_courant).suivant; } } else { while(l_element_courant != NULL) { 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 *) (*(*l_element_courant).donnee).objet)).thread).tid, (*s_argument_thread).tid) != 0) { while(read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_objets_attente[0], &tid_candidat, sizeof(tid_candidat)) == sizeof(tid_candidat)) { /* * -1 est renvoyé par l'instruction SWI */ if (tid_candidat == (pthread_t) -2) { break; } else if (tid_candidat == (pthread_t) -1) { } else if (read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_objets_attente[0], &tid_candidat, sizeof(tid_candidat)) == sizeof(tid_candidat)) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Données en provenance du " "thread %llu (thread " "arrêté)\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Data from thread %llu " "(thread stopped)\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } } } break; } l_element_courant = (*l_element_courant).suivant; } } } l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; if (drapeau_interruptions_traitees == d_faux) { if ((*s_argument_thread).processus_detache == d_vrai) { while(l_element_courant != NULL) { 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 *) (*(*l_element_courant) .donnee).objet)).thread).pid == (*s_argument_thread).pid) { while(read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_interruptions_attente[0], &pid_candidat, sizeof(pid_candidat)) == sizeof(pid_candidat)) { if (pid_candidat == -2) { break; } else if (pid_candidat == -1) { } else if (read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_interruptions_attente[0], &pid_candidat, sizeof(pid_candidat)) == sizeof(pid_candidat)) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_traitement_interruption) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Interruption logicielle " "en provenance du processus %d" " (processus arrêté)\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Software interrupt " "from process %d (processus " "stopped)\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee) .objet)).thread) .nombre_interruptions_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*s_etat_processus) .nombre_interruptions_non_affectees++; } } break; } l_element_courant = (*l_element_courant).suivant; } } else { while(l_element_courant != NULL) { 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 *) (*(*l_element_courant).donnee).objet)).thread).tid, (*s_argument_thread).tid) != 0) { while(read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_interruptions_attente[0], &tid_candidat, sizeof(tid_candidat)) == sizeof(tid_candidat)) { if (tid_candidat == (pthread_t) -2) { break; } else if (tid_candidat == (pthread_t) -1) { } else if (read_atomic(s_etat_processus, (*s_argument_thread) .pipe_nombre_interruptions_attente[0], &tid_candidat, sizeof(tid_candidat)) == sizeof(tid_candidat)) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_traitement_interruption) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Interruption logicielle " "en provenance du thread %llu" " (thread arrêté)\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Software interrupt " "from thread %llu (thread " "stopped)\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee) .objet)).thread) .nombre_interruptions_dans_pipe++; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } (*s_etat_processus) .nombre_interruptions_non_affectees++; } } break; } l_element_courant = (*l_element_courant).suivant; } } } if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } /* * Traitement des interruptions et des erreurs. */ if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Récupération des erreurs du processus " "%d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Check errors from process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } else { if ((*s_etat_processus).langue == 'F') { printf("[%d] Récupération des erreurs du thread " "%llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Check errors from process %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } } } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, (*s_argument_thread).pipe_erreurs[0], &((*s_etat_processus).erreur_execution_processus_fils), sizeof((*s_etat_processus).erreur_execution_processus_fils)) != sizeof((*s_etat_processus).erreur_execution_processus_fils)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, (*s_argument_thread).pipe_erreurs[0], &tampon_erreur, sizeof((*s_etat_processus).erreur_systeme_processus_fils)) != sizeof((*s_etat_processus).erreur_systeme_processus_fils)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } (*s_etat_processus).erreur_systeme_processus_fils = tampon_erreur; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, (*s_argument_thread).pipe_erreurs[0], &((*s_etat_processus).pid_erreur_processus_fils), sizeof((*s_etat_processus).pid_erreur_processus_fils)) != sizeof((*s_etat_processus).pid_erreur_processus_fils)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } /* * Si une erreur est déclarée dans le processus fils, le message * d'erreur a déjà été affiché. */ if (((*s_etat_processus).erreur_systeme_processus_fils != d_es) || ((*s_etat_processus).erreur_execution_processus_fils != d_ex)) { (*s_etat_processus).erreur_processus_fils = d_vrai; (*s_etat_processus).invalidation_message_erreur = d_vrai; } /* * Retrait du processus de la pile des processus */ if (close((*s_argument_thread).pipe_erreurs[0]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } else { do { drapeau_fin = d_faux; l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; nombre_donnees = -1; while(l_element_courant != NULL) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache == d_vrai) { if ((*s_argument_thread).pid == (*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).pid) { if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } nombre_donnees = (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe + (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_interruptions_dans_pipe; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } break; } } } else { if ((*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache == d_faux) { if (pthread_equal((*s_argument_thread).tid, (*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).tid) != 0) { if (pthread_mutex_lock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } nombre_donnees = (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe + (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_interruptions_dans_pipe; if (pthread_mutex_unlock( &((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; } break; } } } l_element_courant = (*l_element_courant).suivant; } if (nombre_donnees == -1) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; drapeau_fin = d_vrai; BUG(1, printf("Process or thread not found")); } else if ((nombre_donnees == 0) || ((*s_etat_processus).var_volatile_requete_arret == -1)) { if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Fermeture des tuyaux du processus " "%d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } else { printf("[%d] Close remaining pipes " "of process %d\n", (int) getpid(), (int) (*s_argument_thread).pid); fflush(stdout); } } else { if ((*s_etat_processus).langue == 'F') { printf("[%d] Fermeture des tuyaux du thread " "%llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread).tid); fflush(stdout); } else { printf("[%d] Close remaining pipes " "of thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread) .tid); fflush(stdout); } } } if (close((*s_argument_thread).pipe_objets[0]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (close((*s_argument_thread).pipe_acquittement[1]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (close((*s_argument_thread).pipe_injections[1]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (close((*s_argument_thread).pipe_nombre_injections[1]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (close((*s_argument_thread) .pipe_nombre_objets_attente[0]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (close((*s_argument_thread) .pipe_interruptions[0]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } if (close((*s_argument_thread) .pipe_nombre_interruptions_attente[0]) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } drapeau_fin = d_vrai; } else { if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; drapeau_fin = d_vrai; } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; drapeau_fin = d_vrai; } } } while(drapeau_fin == d_faux); l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; l_element_precedent = NULL; while(l_element_courant != NULL) { drapeau = d_faux; if ((*s_argument_thread).processus_detache == (*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).pid == (*s_argument_thread).pid) { drapeau = d_vrai; } else { drapeau = d_faux; } } else { if (pthread_equal((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).tid, (*s_argument_thread).tid) != 0) { drapeau = d_vrai; } else { drapeau = d_faux; } } } else { drapeau = d_faux; } if (drapeau == d_vrai) { if (l_element_precedent == NULL) { (*s_etat_processus).l_base_pile_processus = (*l_element_courant).suivant; free(l_element_courant); l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; } else { (*l_element_precedent).suivant = (*l_element_courant).suivant; free(l_element_courant); } break; } else { l_element_precedent = l_element_courant; l_element_courant = (*l_element_courant).suivant; } } if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) { if ((*s_argument_thread).processus_detache == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Arrêt du thread de surveillance du" " processus %d\n", (int) getpid(), (int) (*s_argument_thread).pid); } else { printf("[%d] Stop monitoring of process %d", (int) getpid(), (int) (*s_argument_thread).pid); } } else { if ((*s_etat_processus).langue == 'F') { printf("[%d] Arrêt du thread de surveillance du" " thread %llu\n", (int) getpid(), (unsigned long long) (*s_argument_thread) .tid); } else { printf("[%d] Stop monitoring of thread %llu", (int) getpid(), (unsigned long long) (*s_argument_thread) .tid); } } fflush(stdout); } retrait_thread_surveillance(s_etat_processus, s_argument_thread); pthread_exit(NULL); } /* ================================================================================ Fonction d'écriture dans un pipe ================================================================================ Entrées : pointeur sur une structure de description du processus, numéro du pipe et objet à écrire -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 ecriture_pipe(struct_processus *s_etat_processus, int pipe, struct_objet *s_objet) { struct_liste_chainee *l_element_courant; struct timespec attente; unsigned long i; unsigned long j; size_t longueur; ssize_t longueur_ecriture; if ((*s_objet).type == INT) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (integer8 *) (*s_objet).objet, sizeof(integer8))) != sizeof(integer8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == REL) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (real8 *) (*s_objet).objet, sizeof(real8))) != sizeof(real8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == CPL) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (real8 *) (*s_objet).objet, sizeof(complex16))) != sizeof(complex16)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == VIN) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_vecteur *) (*s_objet).objet)) .taille), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_vecteur *) (*s_objet).objet)).taille; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &(((integer8 *) (*((struct_vecteur *) (*s_objet).objet)) .tableau)[i]), sizeof(integer8))) != sizeof(integer8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } else if ((*s_objet).type == VRL) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_vecteur *) (*s_objet).objet)) .taille), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_vecteur *) (*s_objet).objet)).taille; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &(((real8 *) (*((struct_vecteur *) (*s_objet).objet)) .tableau)[i]), sizeof(real8))) != sizeof(real8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } else if ((*s_objet).type == VCX) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_vecteur *) (*s_objet).objet)) .taille), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_vecteur *) (*s_objet).objet)).taille; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &(((complex16 *) (*((struct_vecteur *) (*s_objet).objet)) .tableau)[i]), sizeof(complex16))) != sizeof(complex16)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } else if ((*s_objet).type == MIN) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_lignes), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_colonnes), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { for(j = 0; j < (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes; j++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &(((integer8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]), sizeof(integer8))) != sizeof(integer8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } } else if ((*s_objet).type == MRL) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_lignes), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_colonnes), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { for(j = 0; j < (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes; j++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &(((real8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]), sizeof(real8))) != sizeof(real8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } } else if ((*s_objet).type == MCX) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_lignes), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_colonnes), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { for(j = 0; j < (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes; j++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &(((complex16 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]), sizeof(complex16))) != sizeof(complex16)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } } else if ((*s_objet).type == BIN) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (integer8 *) (*s_objet).objet, sizeof(integer8))) != sizeof(integer8)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == NOM) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } longueur = strlen((*((struct_nom *) (*s_objet).objet)).nom) + 1; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &longueur, sizeof(size_t))) != sizeof(size_t)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (*((struct_nom *) (*s_objet).objet)).nom, longueur)) != (ssize_t) longueur) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_nom *) (*s_objet).objet)) .symbole), sizeof(logical1))) != sizeof(logical1)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == FCT) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } longueur = strlen((*((struct_fonction *) (*s_objet).objet)).nom_fonction) + 1; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &longueur, sizeof(size_t))) != sizeof(size_t)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (*((struct_fonction *) (*s_objet).objet)) .nom_fonction, longueur)) != (ssize_t) longueur) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_fonction *) (*s_objet).objet)).nombre_arguments), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == CHN) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } longueur = strlen((unsigned char *) (*s_objet).objet) + 1; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &longueur, sizeof(size_t))) != sizeof(size_t)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, (unsigned char *) (*s_objet).objet, longueur)) != (ssize_t) longueur) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if (((*s_objet).type == LST) || ((*s_objet).type == ALG) || ((*s_objet).type == RPN)) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } l_element_courant = (*s_objet).objet; i = 0; while(l_element_courant != NULL) { i++; l_element_courant = (*l_element_courant).suivant; } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &i, sizeof(i))) != sizeof(i)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } l_element_courant = (*s_objet).objet; while(l_element_courant != NULL) { if (ecriture_pipe(s_etat_processus, pipe, (*l_element_courant).donnee) == d_erreur) { return(d_erreur); } l_element_courant = (*l_element_courant).suivant; } } else if ((*s_objet).type == TBL) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type))) != sizeof((*s_objet).type)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while((longueur_ecriture = write_atomic(s_etat_processus, pipe, &((*((struct_tableau *) (*s_objet).objet)).nombre_elements), sizeof(unsigned long))) != sizeof(unsigned long)) { if (longueur_ecriture == -1) { return(d_erreur); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } for(i = 0; i < (*((struct_tableau *) (*s_objet).objet)).nombre_elements; i++) { if (ecriture_pipe(s_etat_processus, pipe, (*((struct_tableau *) (*s_objet).objet)).elements[i]) == d_erreur) { return(d_erreur); } } } else { (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return(d_erreur); } return(d_absence_erreur); } /* ================================================================================ Fonction de lecture dans un pipe ================================================================================ Entrées : pointeur sur une structure de description du processus, numéro du pipe et objet à écrire -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ struct_objet * lecture_pipe(struct_processus *s_etat_processus, int pipe) { size_t longueur; struct_liste_chainee *l_element_courant; struct_objet *s_objet; struct timespec attente; unsigned long i; unsigned long j; if ((s_objet = allocation(s_etat_processus, NON)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*s_objet).type), sizeof((*s_objet).type)) != sizeof((*s_objet).type)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if ((*s_objet).type == INT) { if (((*s_objet).objet = malloc(sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (*s_objet).objet, sizeof(integer8)) != sizeof(integer8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == REL) { if (((*s_objet).objet = malloc(sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (*s_objet).objet, sizeof(real8)) != sizeof(real8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == CPL) { if (((*s_objet).objet = malloc(sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (*s_objet).objet, sizeof(complex16)) != sizeof(complex16)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == VIN) { if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_vecteur *) (*s_objet).objet)).type = 'I'; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_vecteur *) (*s_objet).objet)).taille), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_vecteur *) (*s_objet).objet)).tableau = malloc((*((struct_vecteur *) (*s_objet).objet)).taille * sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_vecteur *) (*s_objet).objet)).taille; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &(((integer8 *) (*((struct_vecteur *) (*s_objet).objet)).tableau)[i]), sizeof(integer8)) != sizeof(integer8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } else if ((*s_objet).type == VRL) { if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_vecteur *) (*s_objet).objet)).type = 'R'; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_vecteur *) (*s_objet).objet)).taille), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_vecteur *) (*s_objet).objet)).tableau = malloc((*((struct_vecteur *) (*s_objet).objet)).taille * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_vecteur *) (*s_objet).objet)).taille; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &(((real8 *) (*((struct_vecteur *) (*s_objet).objet)).tableau)[i]), sizeof(real8)) != sizeof(real8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } else if ((*s_objet).type == VCX) { if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_vecteur *) (*s_objet).objet)).type = 'C'; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_vecteur *) (*s_objet).objet)).taille), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_vecteur *) (*s_objet).objet)).tableau = malloc((*((struct_vecteur *) (*s_objet).objet)).taille * sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_vecteur *) (*s_objet).objet)).taille; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &(((complex16 *) (*((struct_vecteur *) (*s_objet).objet)).tableau)[i]), sizeof(complex16)) != sizeof(complex16)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } else if ((*s_objet).type == MIN) { if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_matrice *) (*s_objet).objet)).type = 'I'; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_lignes), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_colonnes), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_matrice *) (*s_objet).objet)).tableau = malloc((*((struct_matrice *) (*s_objet).objet)).nombre_lignes * sizeof(integer8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { if ((((*((struct_matrice *) (*s_objet).objet)).tableau)[i] = malloc((*((struct_matrice *) (*s_objet).objet)) .nombre_colonnes * sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(j = 0; j < (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes; j++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &(((integer8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]), sizeof(integer8)) != sizeof(integer8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } } else if ((*s_objet).type == MRL) { if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_matrice *) (*s_objet).objet)).type = 'R'; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_lignes), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_colonnes), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_matrice *) (*s_objet).objet)).tableau = malloc((*((struct_matrice *) (*s_objet).objet)).nombre_lignes * sizeof(real8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { if ((((*((struct_matrice *) (*s_objet).objet)).tableau)[i] = malloc((*((struct_matrice *) (*s_objet).objet)) .nombre_colonnes * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(j = 0; j < (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes; j++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &(((real8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]), sizeof(real8)) != sizeof(real8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } } else if ((*s_objet).type == MCX) { if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*((struct_matrice *) (*s_objet).objet)).type = 'C'; attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_lignes), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_matrice *) (*s_objet).objet)).nombre_colonnes), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_matrice *) (*s_objet).objet)).tableau = malloc((*((struct_matrice *) (*s_objet).objet)).nombre_lignes * sizeof(complex16 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { if ((((*((struct_matrice *) (*s_objet).objet)).tableau)[i] = malloc((*((struct_matrice *) (*s_objet).objet)) .nombre_colonnes * sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(j = 0; j < (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes; j++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &(((complex16 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]), sizeof(complex16)) != sizeof(complex16)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } } else if ((*s_objet).type == BIN) { if (((*s_objet).objet = malloc(sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (*s_objet).objet, sizeof(integer8)) != sizeof(integer8)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == NOM) { if (((*s_objet).objet = malloc(sizeof(struct_nom))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &longueur, sizeof(size_t)) != sizeof(size_t)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_nom *) (*s_objet).objet)).nom = malloc(longueur * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (*((struct_nom *) (*s_objet).objet)).nom, longueur) != (ssize_t) longueur) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_nom *) (*s_objet).objet)).symbole), sizeof(logical1)) != sizeof(logical1)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if ((*s_objet).type == FCT) { if (((*s_objet).objet = allocation(s_etat_processus, FCT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &longueur, sizeof(size_t)) != sizeof(size_t)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_fonction *) (*s_objet).objet)).nom_fonction = malloc(longueur * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (*((struct_fonction *) (*s_objet).objet)) .nom_fonction, longueur) != (ssize_t) longueur) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_fonction *) (*s_objet).objet)) .nombre_arguments), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } (*((struct_fonction *) (*s_objet).objet)).fonction = NULL; (*((struct_fonction *) (*s_objet).objet)).prediction_saut = NULL; (*((struct_fonction *) (*s_objet).objet)).prediction_execution = d_faux; } else if ((*s_objet).type == CHN) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &longueur, sizeof(size_t)) != sizeof(size_t)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*s_objet).objet = malloc(longueur * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, (unsigned char *) (*s_objet).objet, longueur) != (ssize_t) longueur) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } else if (((*s_objet).type == LST) || ((*s_objet).type == ALG) || ((*s_objet).type == RPN)) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &j, sizeof(j)) != sizeof(j)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } l_element_courant = NULL; for(i = 0; i < j; i++) { if (l_element_courant == NULL) { if ((l_element_courant = malloc(sizeof(struct_liste_chainee))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } (*s_objet).objet = l_element_courant; } else { if (((*l_element_courant).suivant = malloc(sizeof(struct_liste_chainee))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } l_element_courant = (*l_element_courant).suivant; (*l_element_courant).suivant = NULL; } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(((*l_element_courant).donnee = lecture_pipe(s_etat_processus, pipe)) == NULL) { if ((*s_etat_processus).erreur_systeme != d_es) { return(NULL); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } if (l_element_courant == NULL) { (*s_objet).objet = NULL; } else { (*l_element_courant).suivant = NULL; } } else if ((*s_objet).type == TBL) { if (((*s_objet).objet = malloc(sizeof(struct_tableau))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(read_atomic(s_etat_processus, pipe, &((*((struct_tableau *) (*s_objet).objet)).nombre_elements), sizeof(unsigned long)) != sizeof(unsigned long)) { nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } if (((*((struct_tableau *) (*s_objet).objet)).elements = malloc( (*((struct_tableau *) (*s_objet).objet)).nombre_elements * sizeof(struct_objet *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } for(i = 0; i < (*((struct_tableau *) (*s_objet).objet)).nombre_elements; i++) { attente.tv_sec = 0; attente.tv_nsec = GRANULARITE_us * 1000; while(((*((struct_tableau *) (*s_objet).objet)).elements[i] = lecture_pipe(s_etat_processus, pipe)) == NULL) { if ((*s_etat_processus).erreur_systeme != d_es) { return(NULL); } nanosleep(&attente, NULL); INCR_GRANULARITE(attente.tv_nsec); } } } return(s_objet); } /* ================================================================================ Fonction de scrutation des données injectées par le processus père ================================================================================ Entrées : pointeur sur une structure -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ extern inline void scrutation_injection(struct_processus *s_etat_processus) { fd_set ensemble_descripteurs; # ifndef OpenBSD struct timespec timeout; # else struct timeval timeout; # endif unsigned char tampon; // Si on est dans le processus père, il n'y a rien à surveiller. if ((*s_etat_processus).var_volatile_processus_pere == 0) { FD_ZERO(&ensemble_descripteurs); FD_SET((*s_etat_processus).pipe_nombre_injections, &ensemble_descripteurs); # ifndef OpenBSD timeout.tv_sec = 0; timeout.tv_nsec = 0; if (pselect((*s_etat_processus).pipe_nombre_injections + 1, &ensemble_descripteurs, NULL, NULL, &timeout, NULL) > 0) # else timeout.tv_sec = 0; timeout.tv_usec = 0; if (select((*s_etat_processus).pipe_nombre_injections + 1, &ensemble_descripteurs, NULL, NULL, &timeout) > 0) # endif { if (read_atomic(s_etat_processus, (*s_etat_processus).pipe_nombre_injections, &tampon, sizeof(unsigned char)) == sizeof(unsigned char)) { if (tampon == '-') { (*s_etat_processus).nombre_objets_injectes++; } else if (tampon == '+') { (*s_etat_processus).nombre_objets_envoyes_non_lus--; BUG((*s_etat_processus).nombre_objets_envoyes_non_lus < 0, printf("(*s_etat_processus).nombre_objets_envoyes_" "non_lus=%d\n", (*s_etat_processus) .nombre_objets_envoyes_non_lus)); } else { BUG(1, printf("tampon='%c' (%d)\n", tampon, tampon)); } } } } return; } /* ================================================================================ Fonction de test du drapeau d'arrêt ================================================================================ Entrées : pointeur sur une structure -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ inline int test_arret(struct_processus *s_etat_processus) { return((int) (*s_etat_processus).var_volatile_requete_arret); } // vim: ts=4