Diff for /rpl/src/interruptions.c between versions 1.184 and 1.202

version 1.184, 2016/07/22 15:08:43 version 1.202, 2019/02/11 06:18:20
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.1.25    RPL/2 (R) version 4.1.31
   Copyright (C) 1989-2016 Dr. BERTRAND Joël    Copyright (C) 1989-2019 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 65  thread_surveillance_signaux(void *argume Line 65  thread_surveillance_signaux(void *argume
 {  {
     // Cette fonction est lancée dans un thread créé par processus pour      // Cette fonction est lancée dans un thread créé par processus pour
     // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du      // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du
     // signal SIGALRM. Les processus externes n'envoient plus un signal au      // signal SIGUSR2. Les processus externes n'envoient plus un signal au
     // processus ou au thread à signaler mais positionnent les informations      // processus ou au thread à signaler mais positionnent les informations
     // nécessaires dans la queue des signaux et incrémentent le sémaphore.      // nécessaires dans la queue des signaux et incrémentent le sémaphore.
     // Le sémaphore est décrémenté lorsque le signal est effectivement traité.      // Le sémaphore est décrémenté lorsque le signal est effectivement traité.
   
     int                                     ios;  
     int                                     nombre_signaux_envoyes;      int                                     nombre_signaux_envoyes;
   
     struct_processus                        *s_etat_processus;      struct_processus                        *s_etat_processus;
Line 93  thread_surveillance_signaux(void *argume Line 92  thread_surveillance_signaux(void *argume
   
         if (sem_wait(semaphore_signalisation) == 0)          if (sem_wait(semaphore_signalisation) == 0)
         {          {
             while((ios = sem_wait(semaphore_arret_signalisation)) != 0)              while(sem_wait(semaphore_arret_signalisation) != 0)
             {              {
                 if (errno != EINTR)                  if (errno != EINTR)
                 {                  {
Line 117  thread_surveillance_signaux(void *argume Line 116  thread_surveillance_signaux(void *argume
             // affectée au processus courant pour vérifier s'il y a quelque              // affectée au processus courant pour vérifier s'il y a quelque
             // chose à traiter.              // chose à traiter.
   
             while((ios = sem_wait(semaphore_queue_signaux)) != 0)              while(sem_wait(semaphore_queue_signaux) != 0)
             {              {
                 if (errno != EINTR)                  if (errno != EINTR)
                 {                  {
Line 135  thread_surveillance_signaux(void *argume Line 134  thread_surveillance_signaux(void *argume
                 // appels système lents.                  // appels système lents.
   
                 nombre_signaux_envoyes++;                  nombre_signaux_envoyes++;
                 kill(getpid(), SIGALRM);                  kill(getpid(), SIGUSR2);
                 sched_yield();                  sched_yield();
             }              }
   
Line 168  thread_surveillance_signaux(void *argume Line 167  thread_surveillance_signaux(void *argume
                     {                      {
                         nombre_signaux_envoyes++;                          nombre_signaux_envoyes++;
                         pthread_kill((*((struct_thread *)                          pthread_kill((*((struct_thread *)
                                 (*l_element_courant).donnee)).tid, SIGALRM);                                  (*l_element_courant).donnee)).tid, SIGUSR2);
                         sched_yield();                          sched_yield();
                     }                      }
   
Line 217  modification_pid_thread_pere(struct_proc Line 216  modification_pid_thread_pere(struct_proc
 void  void
 insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)  insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
 {  {
       int                                         ios;
   
       struct timespec                             attente;
   
     volatile struct_liste_chainee_volatile      *l_nouvel_objet;      volatile struct_liste_chainee_volatile      *l_nouvel_objet;
   
     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))      if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
Line 239  insertion_thread(struct_processus *s_eta Line 242  insertion_thread(struct_processus *s_eta
     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =      (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
             s_etat_processus;              s_etat_processus;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      attente.tv_sec = 0;
       attente.tv_nsec = GRANULARITE_us * 1000;
   
       while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          if (ios != EBUSY)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
     }      }
   
     (*l_nouvel_objet).suivant = liste_threads;      (*l_nouvel_objet).suivant = liste_threads;
Line 297  insertion_thread_surveillance(struct_pro Line 324  insertion_thread_surveillance(struct_pro
 void  void
 retrait_thread(struct_processus *s_etat_processus)  retrait_thread(struct_processus *s_etat_processus)
 {  {
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_precedent;      volatile struct_liste_chainee_volatile  *l_element_precedent;
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      attente.tv_sec = 0;
       attente.tv_nsec = GRANULARITE_us * 1000;
   
       while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          if (ios != EBUSY)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
     }      }
   
     l_element_precedent = NULL;      l_element_precedent = NULL;
Line 468  retrait_thread_surveillance(struct_proce Line 523  retrait_thread_surveillance(struct_proce
 void  void
 verrouillage_threads_concurrents(struct_processus *s_etat_processus)  verrouillage_threads_concurrents(struct_processus *s_etat_processus)
 {  {
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      attente.tv_sec = 0;
       attente.tv_nsec = GRANULARITE_us * 1000;
   
       while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
     {      {
         (*s_etat_processus).erreur_systeme = d_es_processus;          if (ios != EBUSY)
         return;          {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               (*s_etat_processus).erreur_systeme = d_es_processus;
               return;
           }
   
           nanosleep(&attente, NULL);
           INCR_GRANULARITE(attente.tv_nsec);
   
           while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
           {
               if (errno != EINTR)
               {
                   (*s_etat_processus).erreur_systeme = d_es_processus;
                   return;
               }
           }
     }      }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
Line 492  verrouillage_threads_concurrents(struct_ Line 575  verrouillage_threads_concurrents(struct_
                         .donnee)).s_etat_processus).semaphore_fork) == -1)                          .donnee)).s_etat_processus).semaphore_fork) == -1)
 #           endif  #           endif
             {              {
                 (*s_etat_processus).erreur_systeme = d_es_processus;                  if (errno != EINTR)
                 return;                  {
                       (*s_etat_processus).erreur_systeme = d_es_processus;
                       return;
                   }
             }              }
         }          }
   
Line 1629  thread_signaux(void *argument) Line 1715  thread_signaux(void *argument)
         if (signal != (0xFF & rpl_sigmax))          if (signal != (0xFF & rpl_sigmax))
         {          {
             envoi_signal_processus(getpid(), signal, d_faux);              envoi_signal_processus(getpid(), signal, d_faux);
             // Un signal SIGALRM est envoyé par le thread de surveillance              // Un signal SIGUSR2 est envoyé par le thread de surveillance
             // des signaux jusqu'à ce que les signaux soient tous traités.              // des signaux jusqu'à ce que les signaux soient tous traités.
         }          }
     } while(signal != (0xFF & rpl_sigmax));      } while(signal != (0xFF & rpl_sigmax));
Line 1685  interruption1(int signal) Line 1771  interruption1(int signal)
             break;              break;
   
         default:          default:
             // SIGALRM              // SIGUSR2
             break;              break;
     }      }
   
Line 1902  inline static void Line 1988  inline static void
 signal_int(struct_processus *s_etat_processus, pid_t pid)  signal_int(struct_processus *s_etat_processus, pid_t pid)
 {  {
     struct_processus        *s_thread_principal;      struct_processus        *s_thread_principal;
     volatile sig_atomic_t   exclusion = 0;      pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
   
     verrouillage_gestionnaire_signaux(s_etat_processus);      verrouillage_gestionnaire_signaux(s_etat_processus);
   
Line 1924  signal_int(struct_processus *s_etat_proc Line 2010  signal_int(struct_processus *s_etat_proc
         {          {
             (*s_etat_processus).var_volatile_traitement_sigint = -1;              (*s_etat_processus).var_volatile_traitement_sigint = -1;
   
             while(exclusion == 1);              pthread_mutex_lock(&exclusion);
             exclusion = 1;  
   
             if ((*s_etat_processus).var_volatile_requete_arret == -1)              if ((*s_etat_processus).var_volatile_requete_arret == -1)
             {              {
                 deverrouillage_gestionnaire_signaux(s_etat_processus);                  deverrouillage_gestionnaire_signaux(s_etat_processus);
                 exclusion = 0;                  pthread_mutex_unlock(&exclusion);
                 return;                  return;
             }              }
   
Line 1948  signal_int(struct_processus *s_etat_proc Line 2033  signal_int(struct_processus *s_etat_proc
             (*s_etat_processus).var_volatile_requete_arret = -1;              (*s_etat_processus).var_volatile_requete_arret = -1;
             (*s_etat_processus).var_volatile_alarme = -1;              (*s_etat_processus).var_volatile_alarme = -1;
   
             exclusion = 0;              pthread_mutex_unlock(&exclusion);
         }          }
     }      }
     else      else
Line 2028  sortie_interruption_depassement_pile(voi Line 2113  sortie_interruption_depassement_pile(voi
     return;      return;
 }  }
   
   #ifdef HAVE_SIGSEGV_RECOVERY
 void  void
 interruption_depassement_pile(int urgence, stackoverflow_context_t scp)  interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
 {  {
Line 2044  interruption_depassement_pile(int urgenc Line 2130  interruption_depassement_pile(int urgenc
     interruption3(SIGUSR2);      interruption3(SIGUSR2);
     return;      return;
 }  }
   #endif
   
 int  int
 interruption_violation_access(void *adresse_fautive, int gravite)  interruption_violation_access(void *adresse_fautive, int gravite)
Line 2057  interruption_violation_access(void *adre Line 2144  interruption_violation_access(void *adre
     {      {
         // Il peut s'agir d'un dépassement de pile.          // Il peut s'agir d'un dépassement de pile.
   
         sigsegv_leave_handler(sortie_interruption_depassement_pile,  #       ifdef HAVE_SIGSEGV_RECOVERY
                 (void *) &routine_recursive, NULL, NULL);              sigsegv_leave_handler(sortie_interruption_depassement_pile,
                       (void *) &routine_recursive, NULL, NULL);
   #       else
               sortie_interruption_depassement_pile((void *) &routine_recursive,
                       NULL, NULL);
   #       endif
     }      }
   
     // On est dans une bonne vieille violation d'accès. On essaie      // On est dans une bonne vieille violation d'accès. On essaie
Line 3096  envoi_signal_processus(pid_t pid, enum s Line 3188  envoi_signal_processus(pid_t pid, enum s
 }  }
   
 int  int
 envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)  envoi_signal_thread(struct_processus *s_contexte,
           pthread_t tid, enum signaux_rpl signal)
 {  {
     // Un signal est envoyé d'un thread à un autre thread du même processus.      // Un signal est envoyé d'un thread à un autre thread du même processus.
   
       int                                     ios;
   
       struct timespec                         attente;
   
     volatile struct_liste_chainee_volatile  *l_element_courant;      volatile struct_liste_chainee_volatile  *l_element_courant;
   
     struct_processus                        *s_etat_processus;      struct_processus                        *s_etat_processus;
   
     if (pthread_mutex_lock(&mutex_liste_threads) != 0)      if (s_contexte != NULL)
     {      {
         return(1);          attente.tv_sec = 0;
           attente.tv_nsec = GRANULARITE_us * 1000;
   
           while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
           {
               if (ios != EBUSY)
               {
                   return(1);
               }
   
               if (sem_post(&((*s_contexte).semaphore_fork)) != 0)
               {
                   return(1);
               }
   
               nanosleep(&attente, NULL);
               INCR_GRANULARITE(attente.tv_nsec);
   
               while(sem_wait(&((*s_contexte).semaphore_fork)) != 0)
               {
                   if (errno != EINTR)
                   {
                       return(1);
                   }
               }
           }
       }
       else
       {
           if (pthread_mutex_lock(&mutex_liste_threads) != 0)
           {
               return(1);
           }
     }      }
   
     l_element_courant = liste_threads;      l_element_courant = liste_threads;
Line 3410  creation_queue_signaux(struct_processus Line 3539  creation_queue_signaux(struct_processus
 #       endif  #       endif
 #   endif  #   endif
   
       (*s_queue_signaux).controle = getpid();
   
       if (lancement_thread_signaux(s_etat_processus) == d_erreur)
       {
           (*s_etat_processus).erreur_systeme = d_es_processus;
           return;
       }
   
     // Lancement du thread de récupération des signaux.      // Lancement du thread de récupération des signaux.
   
     if (pthread_attr_init(&attributs) != 0)      if (pthread_attr_init(&attributs) != 0)
Line 3425  creation_queue_signaux(struct_processus Line 3562  creation_queue_signaux(struct_processus
         return;          return;
     }      }
   
     (*s_queue_signaux).controle = getpid();  
   
     if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,      if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
             thread_surveillance_signaux, s_etat_processus) != 0)              thread_surveillance_signaux, s_etat_processus) != 0)
     {      {
Line 3447  creation_queue_signaux(struct_processus Line 3582  creation_queue_signaux(struct_processus
         (*s_etat_processus).erreur_systeme = d_es_processus;          (*s_etat_processus).erreur_systeme = d_es_processus;
         return;          return;
     }      }
 #           endif  #   endif
   
     if (lancement_thread_signaux(s_etat_processus) == d_erreur)  
     {  
         (*s_etat_processus).erreur_systeme = d_es_processus;  
         return;  
     }  
   
     return;      return;
 }  }
Line 3522  destruction_queue_signaux(struct_process Line 3651  destruction_queue_signaux(struct_process
         unsigned char       *nom;          unsigned char       *nom;
 #   endif  #   endif
   
     // On dépile les interruptions pour arrêter les SIGALRM sur      // On dépile les interruptions pour arrêter les SIGUSR2 sur
     // le processus courant.      // le processus courant.
   
     scrutation_interruptions(s_etat_processus);      scrutation_interruptions(s_etat_processus);

Removed from v.1.184  
changed lines
  Added in v.1.202


CVSweb interface <joel.bertrand@systella.fr>