Changes between Version 12 and Version 13 of AS6-TME-B7


Ignore:
Timestamp:
Apr 11, 2022, 8:50:43 PM (2 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AS6-TME-B7

    v12 v13  
    165165
    166166
    167 En cours, nous avons vu le mécanisme de base, le spinlock (ou busylock) réalisant une prise de verrou par attente active et le mutex ayant aussi comme finalité de prendre un verrou, mais cette fois sans attente active, en organisant une liste d'attente des threads. Notez que nous avons présenté les spinlocks pour le noyau et les mutex pour l'utilisateur, mais il est parfaitement possible d'avoir des spinlocks en mode utilisateur (LL et SC ne sont pas des instructions privilégiées) et mutex en mode noyau.
    168 
    169 Il existe d'autres mécanismes de synchronisation, par exemple, les sémaphores, les variables de conditions, les read-write lock, ou les barrières de synchronisation. Nous allons, ici nous intéresser aux barrières.
    170 
    171 Une barrière de synchronisation est utilisée pour synchroniser les étapes de calculs réalisés par plusieurs threads. Supposons que l'on souhaite exécuter deux threads en parallèle et que l'on veuille attendre que les deux aient terminé leur travail avant de recommencer un travail. Il faut que les deux threads se donnent rendez-vous à la fin de leur calcul.
     167En cours, nous avons vu le mécanisme de base, le spinlock (ou busylock) réalisant une prise de verrou par attente active. Nous avons aussi vu le mutex ayant aussi comme finalité de prendre un verrou, mais cette fois sans attente active, en organisant une liste d'attente des threads. Notez que nous avons présenté les spinlocks pour le noyau et les mutex pour l'utilisateur, mais il est parfaitement possible d'avoir des spinlocks en mode utilisateur (LL et SC n'étant pas des instructions privilégiées) et des mutex en mode noyau.
     168
     169Il existe plein d'autres mécanismes de synchronisation, par exemple, les sémaphores, les variables de conditions, les read-write lock, ou les barrières de synchronisation. Nous allons, ici nous intéresser aux barrières.
     170
     171Les barrières de synchronisation sont utilisées pour synchroniser les étapes de calculs réalisés par plusieurs threads. Supposons que l'on souhaite exécuter deux threads en parallèle et que l'on veuille attendre que les deux aient terminé leur travail avant de recommencer un travail. Il faut que les deux threads se donnent rendez-vous à la fin de leur calcul.
     172
     173L'API des barrières est composée de trois functions (prototypes définis dans `ulib/thread.h` pour les appels systèmes coté utilisateur et dans `kernel/ksynchro.h` pour les prototypes de fonctions implémentées) c'est évidemment les mêmes prototypes (si vous ne comprenez pas pourquoi, demandez le moi).
     174
     175{{{#!c
     176//--------------------------------------------------------------------------------------------------
     177// Barrier API
     178//--------------------------------------------------------------------------------------------------
     179
     180/**
     181 * \brief   hidden barrier type, the user do not what is in the barrier structure
     182 */
     183typedef struct thread_barrier_s * thread_barrier_t;
     184
     185/**
     186 * \brief   creates or initialize a barrier depending the value of barrier parameter
     187 * \param   barrier a pointer referencing the barrier, there are two cases
     188 *                  1) if *barrier == NULL then allocate a new barrier, then initialize count
     189 *                  2) if *barrier != NULL it the barrier already exists, just initialize count
     190 * \param   count   number of expected threads for this barrier
     191 * \return  SUCCESS if it all goes fine or
     192 *          EINVAL  The value specified by count is equal to zero.
     193 *          ENOMEM  Insufficient memory exists to initialize the barrier
     194 *          EBUSY   The implementation has detected an attempt to reinitialize a barrier
     195 *                  while it is in use (for example, while being used in a  thread_barrier_wait() 
     196 *                  call) by  another thread.
     197 */
     198extern int thread_barrier_init (thread_barrier_t * barrier, size_t count);
     199
     200/**
     201 * \brief   wait to the referenced barrier, it is a blocking operation for all thread but the last
     202 *          the last arrived thread doesn't wait and notifies the other threads which becomes READY
     203 * \param   barrier a pointer referencing a barrier
     204 * \return  SUCCESS or FEALURE
     205 */
     206extern int thread_barrier_wait (thread_barrier_t * barrier);
     207
     208/**
     209 * \brief   destroy the referenced barrier
     210 *          If a thread is waiting at the barrier, then the destruction is not done, it is an error
     211 * \param   barrier a pointer referencing a barrier
     212 * \return  SUCCESS if it all goes fine or
     213 *          EINVAL  wrong argument
     214 *          EBUSY   The implementation has detected an attempt to destroy a barrier
     215 *                  while it is in use (for example, while being used in a  thread_barrier_wait() 
     216 *                  call) by  another thread.
     217 */
     218extern int thread_barrier_destroy (thread_barrier_t * barrier);
     219
     220}}}
    172221
    173222{{{#!c