--- rpl/src/rpl.h 2013/03/21 14:13:55 1.214 +++ rpl/src/rpl.h 2015/01/08 14:29:52 1.257 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.13 - Copyright (C) 1989-2013 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.20 + Copyright (C) 1989-2015 Dr. BERTRAND Joël This file is part of RPL/2. @@ -56,6 +56,10 @@ # define sched_yield(arg) #endif +#ifdef CYGWIN +# define SA_ONSTACK 0 +#endif + /* ================================================================================ @@ -73,6 +77,7 @@ #include #include #include +#include #ifndef RPLARGS # include @@ -154,7 +159,6 @@ # endif # include -# include # include # include # include @@ -224,7 +228,7 @@ # include #endif -// Définition spécifique à Hurd +// Définition spécifique à Hurd #ifndef PIPE_BUF # define fpathconf (".", _PC_PIPE_BUF) #endif @@ -262,11 +266,11 @@ /* ================================================================================ - Bugs spécifiques + Bugs spécifiques ================================================================================ */ -// Néant +// Néant /* ================================================================================ @@ -288,17 +292,17 @@ enum signaux_rpl rpl_signull = 0, rpl_sigint, rpl_sigterm, - rpl_sigstart, // Signal envoyé par un père pour lancer son fils. - rpl_sigcont, // Signal de redémarrage d'un processus arrêté par + rpl_sigstart, // Signal envoyé par un père pour lancer son fils. + rpl_sigcont, // Signal de redémarrage d'un processus arrêté par // SUSPEND - rpl_sigstop, // Signal d'arrêt envoyé par l'instruction STOP ou + rpl_sigstop, // Signal d'arrêt envoyé par l'instruction STOP ou // FUSE. (FSTOP) - rpl_sigabort, // Signal envoyé par l'instruction ABORT (à regrouper + rpl_sigabort, // Signal envoyé par l'instruction ABORT (à regrouper // avec FABORT) - rpl_sigurg, // Signal d'arrêt urgent - rpl_siginject, // Signal indiquant la présence d'une donnée à lire - // envoyée depuis le père - rpl_sigalrm, // Signal d'alarme (erreur système) depuis un fils + rpl_sigurg, // Signal d'arrêt urgent + rpl_siginject, // Signal indiquant la présence d'une donnée à lire + // envoyée depuis le père + rpl_sigalrm, // Signal d'alarme (erreur système) depuis un fils rpl_sighup, rpl_sigtstp, rpl_sigexcept, @@ -307,41 +311,39 @@ enum signaux_rpl #define LONGUEUR_QUEUE_SIGNAUX 1024 -// Une structure s_queue_signaux est créée par processus (et non par thread). -// Elle est projetée dans un segment de mémoire partagée pour qu'elle soit -// accessible à la fois du père et des fils. +// Une structure s_queue_signaux est créée par processus (et non par thread). +// Elle est projetée dans un segment de mémoire partagée pour qu'elle soit +// accessible à la fois du père et des fils. #ifndef RPLARGS typedef struct queue_signaux { -# ifndef IPCS_SYSV -# ifndef SEMAPHORES_NOMMES - sem_t semaphore; - sem_t signalisation; -# endif -# else - sem_t semaphore; - sem_t signalisation; -# endif - volatile int pointeur_lecture; volatile int pointeur_ecriture; - pthread_t thread_signaux; volatile logical1 requete_arret; + pthread_t thread_signaux; + volatile struct { pid_t pid; enum signaux_rpl signal; } queue[LONGUEUR_QUEUE_SIGNAUX]; + +# ifdef OS2 + sem_t semaphore; + sem_t signalisation; + sem_t arret_signalisation; +# endif } struct_queue_signaux; -__EXTERN__ struct_queue_signaux *s_queue_signaux; -__EXTERN__ int f_queue_signaux; +__EXTERN__ struct_queue_signaux *s_queue_signaux; +__EXTERN__ int f_queue_signaux; -# ifdef SEMAPHORES_NOMMES - __EXTERN__ sem_t *semaphore_queue_signaux; - __EXTERN__ sem_t *semaphore_signalisation; +# ifndef OS2 + __EXTERN__ sem_t *semaphore_queue_signaux; + __EXTERN__ sem_t *semaphore_signalisation; + __EXTERN__ sem_t *semaphore_arret_signalisation; # endif #endif @@ -370,21 +372,64 @@ union semun /* ================================================================================ - SÉMAPHORES + SÉMAPHORES ================================================================================ */ #ifdef IPCS_SYSV +# ifdef DEBUG_SEMAPHORES +# define sem_wait(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "waiting at %s() " \ + "line #%d\n", (int) getpid(), (unsigned long long) i\ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ + if (value > 1) BUG(1, uprintf("Value %d\n", value)); \ + sem_wait_SysV(a); }) +# define sem_post(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "posting at %s() " \ + "line #%d\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ + if (value > 0) BUG(1, uprintf("Value %d\n", value)); \ + sem_post_SysV(a); }) +# define sem_destroy(a) ({ int value; sem_getvalue(a, &value); \ + if (value == 0) BUG(1, uprintf("Value %d\n", value)); \ + sem_destroy_SysV(a); }) +# else +# define sem_destroy(a) sem_destroy_SysV(a) +# define sem_wait(a) sem_wait_SysV(a) +# define sem_post(a) sem_post_SysV(a) +# endif + # define sem_init(a, b, c) sem_init_SysV(a, b, c) -# define sem_destroy(a) sem_destroy_SysV(a) -# define sem_wait(a) sem_wait_SysV(a) # define sem_trywait(a) sem_trywait_SysV(a) # define sem_timedwait(a, b) sem_timedwait_SysV(a, b) -# define sem_post(a) sem_post_SysV(a) # define sem_getvalue(a, b) sem_getvalue_SysV(a, b) # define sem_open(...) sem_open_SysV(__VA_ARGS__) # define sem_close(a) sem_close_SysV(a) # define sem_unlink(a) sem_unlink_SysV(a) +#else +# ifdef DEBUG_SEMAPHORES +# define sem_wait(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "waiting at %s() " \ + "line #%d\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ + if (value > 1) BUG(1, uprintf("Value %d\n", value)); sem_wait(a); }) +# define sem_post(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "posting at %s() " \ + "line #%d\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ + if (value > 0) BUG(1, uprintf("Value %d\n", value)); sem_post(a); }) +# define sem_destroy(a) ({ int value; sem_getvalue(a, &value); \ + if (value == 0) BUG(1, uprintf("Value %d\n", value)); \ + sem_destroy(a); }) +# endif #endif @@ -396,12 +441,12 @@ union semun #ifndef RPLARGS -// Signaux utilisés par défaut : +// Signaux utilisés par défaut : // SIGINT // SIGTSTP // SIGCONT // SIGPIPE -// SIGUSR1 et SIGUSR2 sont utilisé par libsigsegv. +// SIGUSR1 et SIGUSR2 sont utilisé par libsigsegv. // SIGHUP // SIGALRM @@ -413,7 +458,7 @@ union semun /* ================================================================================ - Granularité temporelle + Granularité temporelle ================================================================================ */ @@ -455,9 +500,6 @@ union semun #ifndef RPLARGS # ifdef SEMAPHORES_NOMMES # define LONGUEUR_NOM_SEMAPHORE 64 -# endif - -# ifdef SEMAPHORES_NOMMES # define __PTR__ * # else # define __PTR__ @@ -473,40 +515,34 @@ union semun __EXTERN__ pid_t pid_processus_pere; -# ifdef SEMAPHORES_NOMMES - __EXTERN__ pthread_mutex_t mutex_sem __STATIC_MUTEX_INITIALIZATION__; -# endif - __EXTERN__ pthread_mutex_t mutex_liste_threads __STATIC_MUTEX_INITIALIZATION__; - __EXTERN__ pthread_mutex_t mutex_gestionnaires_signaux_atomique - __STATIC_MUTEX_INITIALIZATION__; __EXTERN__ pthread_mutex_t mutex_creation_variable_partagee __STATIC_MUTEX_INITIALIZATION__; __EXTERN__ pthread_mutex_t mutex_sections_critiques; __EXTERN__ pthread_mutex_t mutex_liste_variables_partagees; - - __EXTERN__ sem_t __PTR__ semaphore_gestionnaires_signaux; + __EXTERN__ pthread_mutex_t mutex_sem __STATIC_MUTEX_INITIALIZATION__; __EXTERN__ volatile int routine_recursive; -#endif -#ifdef SEMAPHORES_NOMMES -#define SEM_FORK 0 -#define SEM_QUEUE 1 -#define SEM_SIGNAUX 2 -#define SEM_SIGNALISATION 3 -sem_t *sem_init2(unsigned int valeur, pid_t pid, int ordre); -sem_t *sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre); -int sem_destroy2(sem_t *semaphore_p, pid_t pid, int ordre); -int sem_destroy3(sem_t *semaphore_p, pid_t pid, pthread_t tid, int ordre); -int sem_getvalue2(sem_t *semaphore, int *valeur); -sem_t *sem_open2(pid_t pid, int ordre); +# define SEM_FORK 0 +# define SEM_QUEUE 1 +# define SEM_SIGNALISATION 2 +# define SEM_ARRET_SIGNALISATION 3 + + sem_t *sem_init2(unsigned int valeur, pid_t pid, int ordre); + sem_t *sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre); + int sem_destroy2(sem_t *semaphore_p, pid_t pid, int ordre); + int sem_destroy3(sem_t *semaphore_p, pid_t pid, pthread_t tid, int ordre); + int sem_getvalue2(sem_t *semaphore, int *valeur); + sem_t *sem_open2(pid_t pid, int ordre); +#endif -// Le mutex est là uniquement pour pouvoir émuler le comportement -// de sem_getvalue() sur un système comme MacOS X qui ne possède pas +// Le mutex est là uniquement pour pouvoir émuler le comportement +// de sem_getvalue() sur un système comme MacOS X qui ne possède pas // cette fonction. +#ifdef Darwin #define sem_getvalue(semaphore, value) sem_getvalue2(semaphore, value) #define sem_post(semaphore) \ ({ int r; pthread_mutex_lock(&mutex_sem); \ @@ -525,7 +561,7 @@ sem_t *sem_open2(pid_t pid, int ordre); ================================================================================ */ -// Par défaut, tout est redirigé vers stderr sauf indication explicite de +// Par défaut, tout est redirigé vers stderr sauf indication explicite de // stdout. #define printf(...) transliterated_fprintf(s_etat_processus, \ @@ -557,8 +593,8 @@ sem_t *sem_open2(pid_t pid, int ordre); # define fflush(flux) fflush((flux == stdout) ? stderr : flux) #endif -// Ajout d'un timeout sur les fonctions pipe() pour éviter une erreur -// système dans le cas où l'on a atteint le nombre maximale de fichiers +// Ajout d'un timeout sur les fonctions pipe() pour éviter une erreur +// système dans le cas où l'on a atteint le nombre maximale de fichiers // ouverts. #define pipe(descripteurs) \ @@ -577,14 +613,14 @@ sem_t *sem_open2(pid_t pid, int ordre); erreur; \ }) -// Redéfinition de abs pour un fonctionnement en entier de type long long int +// Redéfinition de abs pour un fonctionnement en entier de type long long int #ifdef __GNUC__ # define abs(i) ({ typeof(i) _i; _i = (i); (_i >= 0) ? _i : -_i; }) -// typeof() est une extension de gcc, mais est présent sur d'autres compilateurs -// comme Sun Studio. Dans le cas où typeof() n'existe pas, il est possible -// d'utiliser la macro suivante, mais elle possède un effet de bord dû à -// l'évaluation multiple de l'argument. +// typeof() est une extension de gcc, mais est présent sur d'autres compilateurs +// comme Sun Studio. Dans le cas où typeof() n'existe pas, il est possible +// d'utiliser la macro suivante, mais elle possède un effet de bord dû à +// l'évaluation multiple de l'argument. #else # define abs(i) (((i) >= 0) ? (i) : (-i)) #endif @@ -691,23 +727,6 @@ pid_t debug_fork(); pthread_mutex_unlock(mutex) #endif -#ifdef DEBUG_SEMAPHORES -#define sem_wait(a) ({ int value; sem_getvalue(a, &value); \ - uprintf("[%d-%llu] Semaphore %s (%p) "\ - "waiting at %s() " \ - "line #%d\n", (int) getpid(), (unsigned long long) pthread_self(), \ - #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ - if (value > 1) BUG(1, uprintf("Value %d\n", value)); sem_wait(a); }) -#define sem_post(a) ({ int value; sem_getvalue(a, &value); \ - uprintf("[%d-%llu] Semaphore %s (%p) "\ - "posting at %s() " \ - "line #%d\n", (int) getpid(), (unsigned long long) pthread_self(), \ - #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ - if (value > 0) BUG(1, uprintf("Value %d\n", value)); sem_post(a); }) -#define sem_destroy(a) ({ int value; sem_getvalue(a, &value); \ - if (value == 0) BUG(1, uprintf("Value %d\n", value)); sem_destroy(a); }) -#endif - /* ================================================================================ @@ -759,7 +778,7 @@ pid_t debug_fork(); /* -------------------------------------------------------------------------------- - Paramètres du système + Paramètres du système -------------------------------------------------------------------------------- */ @@ -778,7 +797,7 @@ pid_t debug_fork(); /* -------------------------------------------------------------------------------- - Erreurs système + Erreurs système -------------------------------------------------------------------------------- */ @@ -804,7 +823,7 @@ pid_t debug_fork(); #endif -// -1 : erreur provoquée par une bibliothèque externe +// -1 : erreur provoquée par une bibliothèque externe #ifndef RPLARGS # define d_es 2000 # define d_es_allocation_memoire __erreur(2001) @@ -870,11 +889,11 @@ pid_t debug_fork(); /* -------------------------------------------------------------------------------- - Erreurs à l'exécution + Erreurs à l'exécution -------------------------------------------------------------------------------- */ -// -1 : erreur provoquée par une bibliothèque externe +// -1 : erreur provoquée par une bibliothèque externe #ifndef RPLARGS # define d_ex 0 # define d_ex_pile_vide __erreur(1) @@ -1026,13 +1045,13 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C SLB, SPH, SQL, TBL, VCX, VIN, VRL }; /* - ADR : adresse sur 64 bits signés. - Adresse d'une définition à interpréter. + ADR : adresse sur 64 bits signés. + Adresse d'une définition à interpréter. - ALG : expression algébrique (struct_liste_chainee *) - La liste chaînée contient la définition convertie en notation - polonaise inversée. Ce type diffère du type 'RPN' au niveau - du format de sortie (notation algébrique). + ALG : expression algébrique (struct_liste_chainee *) + La liste chaînée contient la définition convertie en notation + polonaise inversée. Ce type diffère du type 'RPN' au niveau + du format de sortie (notation algébrique). BIN : entier binaire sur 64 bits (unsigned integer8 *) Sans objet. @@ -1047,8 +1066,8 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C FCH : descripteur de fichier (struct_fichier *). - FCT : déclaration d'une fonction et de son nombre d'arguments - (struct_fonction *). Ce type n'est nécessaire que dans le + FCT : déclaration d'une fonction et de son nombre d'arguments + (struct_fonction *). Ce type n'est nécessaire que dans le traitement des types 'ALG' et 'RPN'. INT : entier sur 64 bits (integer*8, integer8 *) @@ -1056,10 +1075,10 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C Type C/Fortran : integer8 LST : liste (struct_liste_chainee *) - Les objets sont enregistrés sous forme de liste chaînée récursive. - Cela permet de traiter des tableaux de données hétérogènes de - grandes dimensions. Le nombre de dimensions maximal est fixé par - la mémoire de la station. + Les objets sont enregistrés sous forme de liste chaînée récursive. + Cela permet de traiter des tableaux de données hétérogènes de + grandes dimensions. Le nombre de dimensions maximal est fixé par + la mémoire de la station. MCX : matrice de complexes (struct_matrice *) Sans objet. @@ -1083,17 +1102,17 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C Sans objet. RPN : definition (struct_liste_chainee *) - Ce type diffère du type 'ALG' au niveau du format de sortie - (notation polonaise inversée). + Ce type diffère du type 'ALG' au niveau du format de sortie + (notation polonaise inversée). SCK : socket (struct_socket *) - SLB : bibliothèque dynamique partagée (struct_bibliotheque *) + SLB : bibliothèque dynamique partagée (struct_bibliotheque *) Sans objet. - SPH : sémaphore nommé (struct_semaphore *) + SPH : sémaphore nommé (struct_semaphore *) - SQL : connecteur sur une base de données SQL (struct_connecteur_sql *) + SQL : connecteur sur une base de données SQL (struct_connecteur_sql *) TBL : tableau multidimensionnel d'objets (struct_tableau *). @@ -1163,7 +1182,7 @@ typedef struct rpl_mutex /* -------------------------------------------------------------------------------- - Structure sémaphore + Structure sémaphore -------------------------------------------------------------------------------- */ @@ -1195,7 +1214,7 @@ typedef struct marque /* -------------------------------------------------------------------------------- - Structure bibliothèque + Structure bibliothèque -------------------------------------------------------------------------------- */ @@ -1320,7 +1339,7 @@ typedef struct socket /* -------------------------------------------------------------------------------- - Structure liste chaînee + Structure liste chaînee -------------------------------------------------------------------------------- */ @@ -1345,8 +1364,8 @@ typedef struct gestion_signaux unsigned char masque_signaux[d_NOMBRE_SIGNAUX]; /* - * 'I' : signal ignoré - * 'Q' : signal mis en queue pour un traitement ultérieur + * 'I' : signal ignoré + * 'Q' : signal mis en queue pour un traitement ultérieur * 'N' : traitement normal du signal */ @@ -1394,7 +1413,7 @@ typedef struct liste_profilage2 /* -------------------------------------------------------------------------------- - Structure contenant les fichiers graphiques (liste chaînée) + Structure contenant les fichiers graphiques (liste chaînée) -------------------------------------------------------------------------------- */ @@ -1426,7 +1445,7 @@ typedef struct nom { unsigned char *nom; logical1 symbole; /* d_vrai/d_faux */ - // symbole == d_vrai signifie que le nom a été introduit dans un + // symbole == d_vrai signifie que le nom a été introduit dans un // calcul sans les apostrophes. } struct_nom; @@ -1460,8 +1479,10 @@ typedef struct descripteur_thread int pipe_injections[2]; int pipe_nombre_injections[2]; int pipe_interruptions[2]; - int pipe_nombre_objets_attente[2]; - int pipe_nombre_interruptions_attente[2]; + // pipe_nombre_elements_attente == 0 => initialisation ou terminaison + // pipe_nombre_elements_attente == 1 => objet en attente + // pipe_nombre_elements_attente == 2 => interruption en attente + int pipe_nombre_elements_attente[2]; int pipe_acquittement[2]; volatile integer8 nombre_objets_dans_pipe; @@ -1506,7 +1527,7 @@ typedef struct liste_pile_systeme clause : I : IF R : IFERR - X : IFERR indiquant la présence d'une erreur. + X : IFERR indiquant la présence d'une erreur. T : THEN E : ELSE Z : traitement en cours de ELSE @@ -1515,8 +1536,8 @@ typedef struct liste_pile_systeme W : WHILE M : WHILE avec une clause fausse. S : SELECT - K : aucun cas CASE n'a encore été traité. - C : au moins un cas de SELECT...CASE a été traité. + K : aucun cas CASE n'a encore été traité. + C : au moins un cas de SELECT...CASE a été traité. Q : traitement en cours d'un cas CASE. F : traitement du cas DEFAULT */ @@ -1527,7 +1548,7 @@ typedef struct liste_pile_systeme unsigned char type_cloture; /* - type clôture : + type clôture : C SELECT : END termine un test SELECT/DEFAULT/END. D DO : END termine une boucle DO/UNTIL/END. I IF : END termine un test IF/THEN (ELSE)/END. @@ -1538,8 +1559,8 @@ typedef struct liste_pile_systeme F FOR : NEXT ou STEP termine une boucle avec compteur. S START : NEXT ou STEP termine une boucle sans compteur. - L LOOP : boucle utilisé dans le traitement de l'instruction RETURN. - Elle correspond à une boucle FOR ou START mais sans son + L LOOP : boucle utilisé dans le traitement de l'instruction RETURN. + Elle correspond à une boucle FOR ou START mais sans son initialisation. A FORALL : NEXT termine une boucle sur un objet. */ @@ -1583,7 +1604,7 @@ typedef struct variable /* -------------------------------------------------------------------------------- - Structure variable partagée + Structure variable partagée -------------------------------------------------------------------------------- */ @@ -1618,7 +1639,7 @@ typedef struct variable_statique unsigned char *nom; unsigned char origine; - // Position de création de la variable statique dans le programme ou dans + // Position de création de la variable statique dans le programme ou dans // l'expression. 'origine' vaut 'P' pour programme ou 'E' pour expression. integer8 niveau; @@ -1685,10 +1706,10 @@ typedef struct tableau typedef struct arbre { - struct_objet *objet; + struct_liste_chainee *feuille; - unsigned long nombre_feuilles; - struct arbre **feuilles; + integer8 nombre_branches; + struct arbre **branches; } struct_arbre; @@ -1726,8 +1747,8 @@ typedef struct rpl_arguments /* Traitement des erreurs */ unsigned char *message_erreur; - unsigned char type_erreur; /* S = système - E = exécution */ + unsigned char type_erreur; /* S = système + E = exécution */ integer8 erreur; /* Traitement des messages d'aide */ @@ -1751,7 +1772,7 @@ typedef struct rpl_arguments /* -------------------------------------------------------------------------------- - Structure d'arbre des instructions intrinsèques + Structure d'arbre des instructions intrinsèques -------------------------------------------------------------------------------- */ @@ -1773,11 +1794,11 @@ typedef struct instruction typedef struct arbre_variables { unsigned int noeuds_utilises; - // Nombre de noeuds utilisés dans le + // Nombre de noeuds utilisés dans le // tableau **noeuds signed int indice_tableau_pere; // Position de la structure dans le - // tableau **noeuds du père + // tableau **noeuds du père struct arbre_variables *noeud_pere; struct arbre_variables **noeuds; @@ -1789,11 +1810,11 @@ typedef struct arbre_variables typedef struct arbre_variables_partagees { unsigned int noeuds_utilises; - // Nombre de noeuds utilisés dans le + // Nombre de noeuds utilisés dans le // tableau **noeuds signed int indice_tableau_pere; // Position de la structure dans le - // tableau **noeuds du père + // tableau **noeuds du père struct arbre_variables_partagees *noeud_pere; struct arbre_variables_partagees **noeuds; @@ -1807,7 +1828,7 @@ typedef struct arbre_variables_partagees do { \ pthread_mutexattr_t attributs_mutex; \ pthread_mutexattr_init(&attributs_mutex); \ - pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); \ + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); \ pthread_mutex_init(&(mutex), &attributs_mutex); \ pthread_mutexattr_destroy(&attributs_mutex); \ } while(0) @@ -1816,7 +1837,7 @@ typedef struct tableau_variables { unsigned char origine; unsigned char *nom; // pointeur sur la struct_variable - // réelle et non copie de la chaîne + // réelle et non copie de la chaîne integer8 niveau; struct_objet *objet; // pointeur sur l'objet et non copie @@ -1824,18 +1845,19 @@ typedef struct tableau_variables logical1 variable_verrouillee; logical1 variable_masquee; + pthread_mutex_t *mutex; union_position_variable variable_statique; union_position_variable variable_partagee; } struct_tableau_variables; -// La liste des variables est une liste doublement chaînée et circulaire. +// La liste des variables est une liste doublement chaînée et circulaire. typedef struct liste_variables { union { // Utilisation dans la gestion des variables struct_variable *variable; - // Utilisation dans la pile système (variables par niveau) + // Utilisation dans la pile système (variables par niveau) struct_liste_chainee *liste; }; @@ -1845,7 +1867,7 @@ typedef struct liste_variables struct liste_variables *precedent; } struct_liste_variables; -// La liste des variables statiques et une liste double chaînée et non +// La liste des variables statiques et une liste double chaînée et non // circulaire. typedef struct liste_variables_statiques { @@ -1868,6 +1890,42 @@ typedef struct liste_variables_partagees } struct_liste_variables_partagees; #endif + +/* +-------------------------------------------------------------------------------- + Structure fonction +-------------------------------------------------------------------------------- +*/ + +#ifndef RPLARGS +typedef struct fonction +{ + unsigned char *nom_fonction; + integer8 nombre_arguments; + + void (*fonction)(struct processus *); + + volatile struct_liste_chainee *prediction_saut; + volatile logical1 prediction_execution; +} struct_fonction; +#endif + + +/* +-------------------------------------------------------------------------------- + Structure buffer +-------------------------------------------------------------------------------- +*/ + +typedef struct buffer +{ + unsigned char *buffer; + + integer8 longueur_requise; + int classe; +} struct_buffer; + + /* -------------------------------------------------------------------------------- Structure processus @@ -1944,8 +2002,7 @@ typedef struct processus int pipe_injections; int pipe_nombre_injections; int pipe_interruptions; - int pipe_nombre_objets_attente; - int pipe_nombre_interruptions_attente; + int pipe_nombre_elements_attente; int nombre_objets_envoyes_non_lus; int nombre_objets_injectes; @@ -1971,13 +2028,13 @@ typedef struct processus /* Variables */ - // La liste des variables par niveau est doublement chaînée. - // À tout moment, elle pointe sur le niveau le plus haut existant et + // La liste des variables par niveau est doublement chaînée. + // À tout moment, elle pointe sur le niveau le plus haut existant et // l_liste_variable_par_niveau->precedent renvoie la liste des - // définitions. l_liste_variable_par_niveau->precedent->precedent pointe + // définitions. l_liste_variable_par_niveau->precedent->precedent pointe // sur la liste des variables globales. // - // À l'initialisation : + // À l'initialisation : // l_liste_variables_par_niveau->suivant == l_liste_variables_par_niveau // l_liste_variables_par_niveau->precedent == l_liste_variables_par_niveau @@ -2016,11 +2073,11 @@ typedef struct processus struct_liste_chainee *s_sockets; -/* Connecteurs aux bases de données */ +/* Connecteurs aux bases de données */ struct_liste_chainee *s_connecteurs_sql; -/* Bibliothèques dynamiques */ +/* Bibliothèques dynamiques */ struct_liste_chainee *s_bibliotheques; struct_instruction_externe *s_instructions_externes; @@ -2181,8 +2238,8 @@ typedef struct processus /* Traitement des erreurs */ int erreur_compilation; - int erreur_execution; - int erreur_systeme; + volatile int erreur_execution; + volatile int erreur_systeme; struct_objet *s_objet_errone; struct_objet *s_objet_erreur; @@ -2222,8 +2279,8 @@ typedef struct processus unsigned char masque_interruptions[d_NOMBRE_INTERRUPTIONS]; /* - * 'I' : interruption ignorée - * 'Q' : interruption mise en queue pour un traitement ultérieur + * 'I' : interruption ignorée + * 'Q' : interruption mise en queue pour un traitement ultérieur * 'N' : traitement normal de l'interruption */ @@ -2245,7 +2302,7 @@ typedef struct processus /* Variables volatiles */ volatile sig_atomic_t var_volatile_alarme; - // Traitement de ctrl+C et des arrêts brutaux + // Traitement de ctrl+C et des arrêts brutaux volatile sig_atomic_t var_volatile_requete_arret; // Traitement de ctrl+Z volatile sig_atomic_t var_volatile_requete_arret2; @@ -2272,12 +2329,12 @@ typedef struct processus integer8 nombre_arguments; /* - * Il s'agit du nombre d'arguments utilisé pour l'évaluation - * des expressions algébriques. - * -1 : la fonction ne peut être dans un objet de type ALG. + * Il s'agit du nombre d'arguments utilisé pour l'évaluation + * des expressions algébriques. + * -1 : la fonction ne peut être dans un objet de type ALG. * -2 : nombre d'arguments inconnu - * 0 : la fonction doit apparaître en notation infixe - * >0 : la fonction apparaît comme une fonction normale + * 0 : la fonction doit apparaître en notation infixe + * >0 : la fonction apparaît comme une fonction normale */ logical1 lancement_interactif; @@ -2295,6 +2352,8 @@ typedef struct processus logical1 processus_detache; + enum t_type type_en_cours; + /* Profilage */ logical1 profilage; @@ -2303,9 +2362,10 @@ typedef struct processus struct_liste_profilage2 *pile_profilage_fonctions; struct timeval horodatage_profilage; - // Mutex spécifique au processus et donnant accès à la pile des processus - pthread_mutex_t mutex; pthread_mutex_t mutex_allocation; + pthread_mutex_t mutex_interruptions; + pthread_mutex_t mutex_pile_processus; + pthread_mutex_t mutex_signaux; // Mutex autorisant les fork() sem_t __PTR__ semaphore_fork; @@ -2316,11 +2376,15 @@ typedef struct processus pthread_mutex_t protection_liste_mutexes; unsigned int sections_critiques; -/* Drapeau nécessaire à RESTART */ +/* Variable d'initialisation pour SCHED */ + + logical1 initialisation_scheduler; + +/* Drapeau nécessaire à RESTART */ volatile logical1 requete_redemarrage; -/* Gestion optimisée de la mémoire */ +/* Gestion optimisée de la mémoire */ double estimation_taille_pile_tampon; integer8 taille_pile_tampon; @@ -2334,82 +2398,40 @@ typedef struct processus struct_objet *pile_objets; # define TAILLE_CACHE 1024 - - integer8 *objets_adr[TAILLE_CACHE]; - int pointeur_adr; - - logical8 *objets_bin[TAILLE_CACHE]; - int pointeur_bin; - - complex16 *objets_cpl[TAILLE_CACHE]; - int pointeur_cpl; - - struct fonction *objets_fct[TAILLE_CACHE]; - int pointeur_fct; - - integer8 *objets_int[TAILLE_CACHE]; - int pointeur_int; - - struct_matrice *objets_mat[TAILLE_CACHE]; - int pointeur_mat; - - struct_nom *objets_nom[TAILLE_CACHE]; - int pointeur_nom; - - real8 *objets_rel[TAILLE_CACHE]; - int pointeur_rel; - - struct_tableau *objets_tab[TAILLE_CACHE]; - int pointeur_tab; - - struct_vecteur *objets_vec[TAILLE_CACHE]; - int pointeur_vec; - - struct_liste_chainee *maillons[TAILLE_CACHE]; - int pointeur_maillons; - - struct_arbre_variables *variables_noeud[TAILLE_CACHE]; - int pointeur_variables_noeud; - - struct_arbre_variables_partagees - *variables_partagees_noeud[TAILLE_CACHE]; - int pointeur_variables_partagees_noeud; - - struct_liste_variables *variables_feuille[TAILLE_CACHE]; - int pointeur_variables_feuille; - - struct_variable *variables_variable[TAILLE_CACHE]; - int pointeur_variables_variable; - - struct_arbre_variables **variables_tableau_noeuds[TAILLE_CACHE]; - int pointeur_variables_tableau_noeuds; - - struct_arbre_variables_partagees - **variables_tableau_noeuds_partages - [TAILLE_CACHE]; - int pointeur_variables_tableau_noeuds_partages; +# define CACHE(type, nom) \ + type *objets_##nom[TAILLE_CACHE]; \ + int pointeur_##nom; + +# define CACHE2(type, nom) \ + type *nom[TAILLE_CACHE]; \ + int pointeur_##nom; + + CACHE(integer8, adr) + CACHE(logical8, bin) + CACHE(complex16, cpl) + CACHE(struct_fonction, fct) + CACHE(integer8, int) + CACHE(struct_matrice, mat) + CACHE(struct_nom, nom) + CACHE(real8, rel) + CACHE(struct_tableau, tab) + CACHE(struct_vecteur, vec) + + CACHE2(struct_liste_chainee, maillons) + CACHE2(struct_arbre_variables, variables_noeud) + CACHE2(struct_arbre_variables_partagees, variables_partagees_noeud) + CACHE2(struct_liste_variables, variables_feuille) + CACHE2(struct_variable, variables_variable) + CACHE2(struct_arbre_variables *, variables_tableau_noeuds) + CACHE2(struct_arbre_variables_partagees *, + variables_tableau_noeuds_partages) + + CACHE2(struct_buffer, enveloppes_buffers) + unsigned char ***cache_buffer; + int *pointeur_cache_buffer; } struct_processus; #endif -/* --------------------------------------------------------------------------------- - Structure fonction --------------------------------------------------------------------------------- -*/ - -#ifndef RPLARGS -typedef struct fonction -{ - unsigned char *nom_fonction; - integer8 nombre_arguments; - - void (*fonction)(struct_processus *); - - volatile struct_liste_chainee *prediction_saut; - volatile logical1 prediction_execution; -} struct_fonction; -#endif - /* ================================================================================ @@ -2419,7 +2441,7 @@ typedef struct fonction /* -------------------------------------------------------------------------------- - Procédures d'exécution des mots-clef du langage RPL/2 + Procédures d'exécution des mots-clef du langage RPL/2 -------------------------------------------------------------------------------- */ @@ -2551,6 +2573,7 @@ void instruction_elseif(struct_processus void instruction_end(struct_processus *s_etat_processus); void instruction_eng(struct_processus *s_etat_processus); void instruction_epsilon(struct_processus *s_etat_processus); +void instruction_eqv(struct_processus *s_etat_processus); void instruction_erase(struct_processus *s_etat_processus); void instruction_errm(struct_processus *s_etat_processus); void instruction_errn(struct_processus *s_etat_processus); @@ -2791,6 +2814,8 @@ void instruction_return(struct_processus void instruction_revlist(struct_processus *s_etat_processus); void instruction_rewind(struct_processus *s_etat_processus); void instruction_rfuse(struct_processus *s_etat_processus); +void instruction_rgdl(struct_processus *s_etat_processus); +void instruction_rgdr(struct_processus *s_etat_processus); void instruction_rl(struct_processus *s_etat_processus); void instruction_rlb(struct_processus *s_etat_processus); void instruction_rnd(struct_processus *s_etat_processus); @@ -2954,7 +2979,7 @@ void instruction_yield(struct_processus /* -------------------------------------------------------------------------------- - Procédures + Procédures -------------------------------------------------------------------------------- */ @@ -3143,7 +3168,7 @@ int envoi_signal_thread(pthread_t tid, e /* -------------------------------------------------------------------------------- - Fonctions de sommation de vecteur dans perte de précision + Fonctions de sommation de vecteur dans perte de précision -------------------------------------------------------------------------------- */ @@ -3189,7 +3214,7 @@ struct_vecteur *variance_statistique(str /* -------------------------------------------------------------------------------- - Gestion des bibliothèques + Gestion des bibliothèques -------------------------------------------------------------------------------- */ @@ -3308,6 +3333,8 @@ logical1 initialisation_fichier_acces_in sqlite3 *sqlite, integer8 position_clef, logical1 binaire); logical1 lancement_thread_signaux(struct_processus *s_etat_processus); logical1 recherche_instruction_suivante(struct_processus *s_etat_processus); +logical1 recherche_instruction_suivante_recursive( + struct_processus *s_etat_processus, integer8 recursivite); logical1 retrait_variable(struct_processus *s_etat_processus, unsigned char *nom_variable, unsigned char type); logical1 retrait_variables_par_niveau(struct_processus *s_etat_processus); @@ -3397,7 +3424,7 @@ unsigned char longueur_entiers_binaires( /* -------------------------------------------------------------------------------- - Fonctions retournant un INTEGER*8 (valeur binaire non signée) + Fonctions retournant un INTEGER*8 (valeur binaire non signée) -------------------------------------------------------------------------------- */ @@ -3421,7 +3448,7 @@ integer8 position_caractere_de_chaine(st /* -------------------------------------------------------------------------------- - Fonctions renvoyant une liste chaînée (pointeur sur *struct_liste_chainee) + Fonctions renvoyant une liste chaînée (pointeur sur *struct_liste_chainee) -------------------------------------------------------------------------------- */ @@ -3432,6 +3459,19 @@ struct_liste_chainee *analyse_rpn(struct /* -------------------------------------------------------------------------------- + Allocateur de buffers à cache +-------------------------------------------------------------------------------- +*/ + +void initialisation_allocateur_buffer(struct_processus *s_etat_processus); +void liberation_allocateur_buffer(struct_processus *s_etat_pocessus); +struct_buffer *allocation_buffer(struct_processus *s_etat_processus, + integer8 longueur); +void liberation_buffer(struct_processus *s_etat_processus, + struct_buffer *buffer); + +/* +-------------------------------------------------------------------------------- Fonctions renvoyant une copie de la structure de description des processus -------------------------------------------------------------------------------- */ @@ -3494,23 +3534,7 @@ struct_liste_variables_partagees *recher /* -------------------------------------------------------------------------------- - Fonctions gérant les arbres de simplification --------------------------------------------------------------------------------- -*/ - -#ifndef RPLARGS -struct_arbre *creation_arbre(struct_processus *s_etat_processus, - struct_objet **t_objets, integer8 indice, integer8 indice_maximal); -void liberation_arbre(struct_processus *s_etat_processus, - struct_arbre *s_noeud); -void parcours_arbre(struct_processus *s_etat_processus, struct_arbre *s_noeud); -void simplification_arbre(struct_processus *s_etat_processus, - struct_arbre *s_noeud); -#endif - -/* --------------------------------------------------------------------------------- - Fonctions gérant la complétion automatique + Fonctions gérant la complétion automatique -------------------------------------------------------------------------------- */ @@ -3522,7 +3546,7 @@ char **completion_matches(); /* -------------------------------------------------------------------------------- - Arithmétique + Arithmétique -------------------------------------------------------------------------------- */ @@ -3566,7 +3590,7 @@ void f77soustractionrc_(real8 *ra, compl /* -------------------------------------------------------------------------------- - Trigonométrie complexe + Trigonométrie complexe -------------------------------------------------------------------------------- */ @@ -3663,7 +3687,7 @@ void zgeev_(unsigned char *calcul_vp_gau integer4 *erreur, integer4 longueur_1, integer4 longueur_2); /* - * Valeurs propres généralisées + * Valeurs propres généralisées */ void zggev_(unsigned char *calcul_vp_gauches, unsigned char *calcul_vp_droits, @@ -3676,7 +3700,7 @@ void zggev_(unsigned char *calcul_vp_gau integer4 *erreur, integer4 longueur_1, integer4 longueur_2); /* - * Moindres carrés + * Moindres carrés */ void dgelsd_(integer4 *nombre_lignes_a, integer4 *nombre_colonnes_a, @@ -3691,11 +3715,11 @@ void zgelsd_(integer4 *nombre_lignes_a, real8 *rwork, integer4 *iwork, integer4 *info); /* - * Moindres carrés généralisé + * Moindres carrés généralisé */ /* - * Décomposition en valeurs singulières + * Décomposition en valeurs singulières */ void dgesvd_(unsigned char *jobu, unsigned char *jobvh, @@ -3752,7 +3776,7 @@ void zgees_(unsigned char *calcul_vecteu real8 *rwork, logical4 *bwork, integer4 *info, integer4 l1, integer4 l2); - /* Déterminant et rang */ + /* Déterminant et rang */ void dgecon_(unsigned char *norm, integer4 *n, real8 *a, integer4 *lda, real8 *anorm, real8 *rcond, real8 *work, integer4 *iwork, integer4 *info, integer4 l1); @@ -3773,8 +3797,8 @@ void zgelsy_(integer4 *m, integer4 *n, i #endif /* - * Fonction testant la requête d'arrêt (nécessaire pour tester le - * drapeau depuis une bibliothèque). + * Fonction testant la requête d'arrêt (nécessaire pour tester le + * drapeau depuis une bibliothèque). */ int test_arret(struct_processus *s_etat_processus);