--- rpl/src/instructions_s1.c 2016/03/16 11:10:47 1.85 +++ rpl/src/instructions_s1.c 2019/02/17 08:59:39 1.103 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.25 - Copyright (C) 1989-2016 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.31 + Copyright (C) 1989-2019 Dr. BERTRAND Joël This file is part of RPL/2. @@ -59,34 +59,34 @@ instruction_swap(struct_processus *s_eta " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf(" 1: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf("-> 2: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf(" 1: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); return; } @@ -3155,10 +3155,10 @@ instruction_sto(struct_processus *s_etat " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" - " %s\n", + " %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SLB, d_PRC, d_MTX, d_SQL); + d_SLB, d_PRC, d_MTX, d_SQL, d_REC); printf(" 1: %s\n", d_NOM); return; @@ -3372,6 +3372,83 @@ instruction_sto(struct_processus *s_etat ================================================================================ */ +struct +{ + struct_processus *s_etat_processus; + struct_liste_chainee *stdin; + int pipe_entree; + volatile int erreur; +} arguments_stdin; + +static void * +thread_stdin(void *argument) +{ + integer8 longueur_ecriture; + + typeof(arguments_stdin) *ptr; + + struct_liste_chainee *l_element_courant; + + struct_processus *s_etat_processus; + + unsigned char *ligne; + + ptr = argument; + + l_element_courant = (*ptr).stdin; + s_etat_processus = (*ptr).s_etat_processus; + (*ptr).erreur = d_es; + + while(l_element_courant != NULL) + { + if ((ligne = formateur_flux(s_etat_processus, + (unsigned char *) (*(*l_element_courant).donnee).objet, + &longueur_ecriture)) == NULL) + { + (*ptr).erreur = d_es_allocation_memoire; + close((*ptr).pipe_entree); + pthread_exit(NULL); + } + + while(write_atomic(s_etat_processus, (*ptr).pipe_entree, ligne, + (size_t) longueur_ecriture) != longueur_ecriture) + { + if (longueur_ecriture == -1) + { + (*ptr).erreur = d_es_processus; + close((*ptr).pipe_entree); + pthread_exit(NULL); + } + } + + free(ligne); + + while(write_atomic(s_etat_processus, (*ptr).pipe_entree, "\n", 1) + != 1) + { + if (longueur_ecriture == -1) + { + (*ptr).erreur = d_es_processus; + close((*ptr).pipe_entree); + pthread_exit(NULL); + } + } + + l_element_courant = (*l_element_courant).suivant; + } + + if (close((*ptr).pipe_entree) != 0) + { + (*ptr).erreur = d_es_processus; + } + else + { + (*ptr).erreur = d_es; + } + + pthread_exit(NULL); +} + void instruction_syseval(struct_processus *s_etat_processus) { @@ -3383,9 +3460,6 @@ instruction_syseval(struct_processus *s_ int pipes_sortie[2]; int status; - integer8 longueur_ecriture; - integer8 longueur_traitee; - logical1 drapeau_fin; logical1 presence_stdin; @@ -3394,6 +3468,10 @@ instruction_syseval(struct_processus *s_ pid_t pid; + pthread_attr_t attributs; + + pthread_t thread_stdin_tid; + struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_precedent; struct_liste_chainee *l_element_stdin; @@ -3406,7 +3484,8 @@ instruction_syseval(struct_processus *s_ struct sigaction action_courante; struct sigaction action_passee; - unsigned char *ligne; + struct timespec attente; + unsigned char *ptr; unsigned char *ptr2; unsigned char registre_autorisation_empilement_programme; @@ -3415,8 +3494,9 @@ instruction_syseval(struct_processus *s_ unsigned char *tampon; integer8 longueur_lecture; + integer8 longueur_lue; integer8 longueur_tampon; - integer8 nombre_iterations; + integer8 longueur_traitee; integer8 nombre_lignes; integer8 pointeur; integer8 registre_position_courante; @@ -3651,23 +3731,6 @@ instruction_syseval(struct_processus *s_ l_element_courant = (*l_element_courant).suivant; } - action_courante.sa_handler = SIG_IGN; - action_courante.sa_flags = SA_NODEFER | SA_ONSTACK; - - if (sigaction(SIGINT, &action_courante, &action_passee) != 0) - { - for(i = 0; i < nombre_arguments; i++) - { - depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), - &s_objet_temporaire); - liberation(s_etat_processus, s_objet_temporaire); - } - - free(arguments); - (*s_etat_processus).erreur_systeme = d_es_signal; - return; - } - if (pipe(pipes_entree) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -3688,7 +3751,54 @@ instruction_syseval(struct_processus *s_ fflush(NULL); + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + + while(pthread_mutex_trylock(&mutex_sigaction) != 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; + } + + nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); + +# ifndef SEMAPHORES_NOMMES + while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) +# else + while(sem_wait((*s_etat_processus).semaphore_fork) != 0) +# endif + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + } + + action_courante.sa_handler = SIG_IGN; + action_courante.sa_flags = 0; + + if (sigaction(SIGINT, &action_courante, &action_passee) != 0) + { + for(i = 0; i < nombre_arguments; i++) + { + depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), + &s_objet_temporaire); + liberation(s_etat_processus, s_objet_temporaire); + } + + free(arguments); + (*s_etat_processus).erreur_systeme = d_es_signal; + return; + } + verrouillage_threads_concurrents(s_etat_processus); + pid = fork(); if (pid < 0) @@ -3821,6 +3931,27 @@ instruction_syseval(struct_processus *s_ } else { + if (sigaction(SIGINT, &action_passee, NULL) != 0) + { + for(i = 0; i < nombre_arguments; i++) + { + depilement(s_etat_processus, + &((*s_etat_processus).l_base_pile), + &s_objet_temporaire); + liberation(s_etat_processus, s_objet_temporaire); + } + + free(arguments); + (*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; + } + deverrouillage_threads_concurrents(s_etat_processus); if (close(pipes_entree[0]) != 0) @@ -3843,189 +3974,43 @@ instruction_syseval(struct_processus *s_ if (presence_stdin == d_vrai) { - l_element_courant = l_element_stdin; + // L'écriture sur stdin est dans un thread séparé pour + // ne pas bloquer. - while(l_element_courant != NULL) + if (pthread_attr_init(&attributs) != 0) { - if ((ligne = formateur_flux(s_etat_processus, - (unsigned char *) (*(*l_element_courant).donnee) - .objet, &longueur_ecriture)) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - -# 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; - } - - while(write_atomic(s_etat_processus, - pipes_entree[1], ligne, - (size_t) longueur_ecriture) != longueur_ecriture) - { -# ifndef SEMAPHORES_NOMMES - while(sem_wait(&((*s_etat_processus) - .semaphore_fork)) != 0) -# else - while(sem_wait((*s_etat_processus) - .semaphore_fork) != 0) -# endif - { - (*s_etat_processus).erreur_systeme = - d_es_processus; - return; - } - - if (longueur_ecriture == -1) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - -# 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; - } - } - - free(ligne); - - while(write_atomic(s_etat_processus, - pipes_entree[1], "\n", 1) != 1) - { -# 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; - } - } - - if (longueur_ecriture == -1) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - -# 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; - } - } - -# 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; - } - } - - l_element_courant = (*l_element_courant).suivant; + (*s_etat_processus).erreur_systeme = d_es_processus; + return; } - } - if (close(pipes_entree[1]) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - - do - { - if (kill(pid, 0) != 0) + if (pthread_attr_setdetachstate(&attributs, + PTHREAD_CREATE_JOINABLE) != 0) { - break; + (*s_etat_processus).erreur_systeme = d_es_processus; + return; } - /* - * Récupération de la valeur de retour du processus détaché - */ + arguments_stdin.s_etat_processus = s_etat_processus; + arguments_stdin.stdin = l_element_stdin; + arguments_stdin.pipe_entree = pipes_entree[1]; -# ifndef SEMAPHORES_NOMMES - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) -# else - if (sem_post((*s_etat_processus).semaphore_fork) != 0) -# endif + if (pthread_create(&thread_stdin_tid, &attributs, thread_stdin, + &arguments_stdin) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } - while(waitpid(pid, &status, 0) == -1) - { - if (errno != EINTR) - { -# 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; - } - - (*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 (pthread_attr_destroy(&attributs) != 0) { - if (errno != EINTR) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } + (*s_etat_processus).erreur_systeme = d_es_processus; + return; } - } while((!WIFEXITED(status)) && (!WIFSIGNALED(status))); + } - longueur_lecture = 256; + longueur_lecture = 65536; + longueur_lue = 0; pointeur = 0; - nombre_iterations = 1; if ((tampon = malloc(((size_t) (longueur_lecture + 1)) * sizeof(unsigned char))) == NULL) @@ -4060,12 +4045,12 @@ instruction_syseval(struct_processus *s_ return; } + longueur_lue += ios; tampon[pointeur + ios] = d_code_fin_chaine; - pointeur += longueur_lecture; - nombre_iterations++; + pointeur += ios; if ((tampon = realloc(tampon, - ((size_t) ((nombre_iterations * longueur_lecture) + 1)) + ((size_t) ((longueur_lue + longueur_lecture) + 1)) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -4097,6 +4082,74 @@ instruction_syseval(struct_processus *s_ } } + if (presence_stdin == d_vrai) + { + if (pthread_join(thread_stdin_tid, NULL) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + + if (arguments_stdin.erreur != d_es) + { + (*s_etat_processus).erreur_systeme = arguments_stdin.erreur; + return; + } + } + else + { + if (close(pipes_entree[1]) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + } + + do + { + if (kill(pid, 0) != 0) + { + // Le processus n'existe plus. + break; + } + + /* + * Récupération de la valeur de retour du processus détaché + */ + +# 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; + } + + while(waitpid(pid, &status, 0) == -1) + { + if (errno != EINTR) + { + (*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; + } + } + } while((!WIFEXITED(status)) && (!WIFSIGNALED(status))); + if (ios == -1) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -4199,20 +4252,6 @@ instruction_syseval(struct_processus *s_ free(tampon); } - if (sigaction(SIGINT, &action_passee, NULL) != 0) - { - for(i = 0; i < nombre_arguments; i++) - { - depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), - &s_objet_temporaire); - liberation(s_etat_processus, s_objet_temporaire); - } - - free(arguments); - (*s_etat_processus).erreur_systeme = d_es_signal; - return; - } - for(i = 0; i < nombre_arguments; i++) { depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), @@ -4220,6 +4259,8 @@ instruction_syseval(struct_processus *s_ liberation(s_etat_processus, s_objet_temporaire); } + free(arguments); + if ((tampon = malloc(sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -4289,7 +4330,6 @@ instruction_syseval(struct_processus *s_ return; } - free(arguments); free(tampon); } else