Changes between Version 15 and Version 16 of AS6-TME-B7


Ignore:
Timestamp:
Apr 11, 2022, 9:13:23 PM (2 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AS6-TME-B7

    v15 v16  
    162162
    163163
    164 == B.1. Mécanisme des barrières
     164== B.1.
     165
     166
     167== B.2.
     168
     169
     170== B.3. Mécanisme des barrières
    165171
    166172
     
    275281}}}
    276282
     283Maintenant, vous n'allez pas avoir à écrire le code des barrières mais voue allez devoir répondre à quelques questions
     284{{{#!c
     285#define MAGIC_BARRIER   0xDEADBABA
     286
     287struct thread_barrier_s {
     288    int         magic;          ///< magic number to check the validity of the barrier
     289    spinlock_t  lock;           ///< protection against parallel modifications
     290    size_t      expected;       ///< number of expected threads
     291    size_t      waiting;        ///< number of threads waiting
     292    list_t      wait;           ///< list element to chain threads that are wainting for the mutex
     293};
     294
     295int thread_barrier_init (thread_barrier_t * barrier, size_t count)
     296{
     297    thread_barrier_t b = *barrier;                          // get the barrier pointer
     298
     299    if (count == 0) return EINVAL;                          // count must be > 0
     300
     301    if (b == NULL) {                                        // if we need a new barrier
     302        b = kmalloc (sizeof (struct thread_barrier_s));     // allocates a new barrier
     303        if (b == NULL) return ENOMEM;                       // test if there is enough memory
     304        b->magic = MAGIC_BARRIER;                           // tell it is a BARRIER
     305        b->lock = 0;                                        // free the lock
     306        b->expected = count;                                // init the expected threads
     307        b->waiting = 0;                                     // init the counter of waiting threads
     308        list_init (&b->wait);                               // init the waiting list
     309        *barrier = b;                                       // at last, init. the return variable
     310        return SUCCESS;                                     // it's fine
     311    }
     312
     313    if (b && (b->magic != MAGIC_BARRIER)) return EINVAL;    // it is not an old barrier
     314
     315    spin_lock (&b->lock);                                   // get the ownership
     316    if (b->waiting != 0) {                                  // if someone is waiting
     317        spin_lock (&b->lock);                               // release the ownership
     318        return EBUSY;                                       // return an error
     319    }
     320
     321    b->expected = count;                                    // set the number of expected threads
     322    spin_lock (&b->lock);                                   // release the ownership
     323
     324    return SUCCESS;                                         // it's fine
     325}
     326
     327int thread_barrier_wait (thread_barrier_t * barrier)
     328{
     329    thread_barrier_t b = *barrier;                          // get the barrier pointer
     330
     331    if (b == NULL) return EINVAL;                           // b is not created
     332    if (b && (b->magic != MAGIC_BARRIER)) return EINVAL;    // check that it is barrier (MAGIC)
     333
     334    spin_lock (&b->lock);                                   // get the ownership
     335    b->waiting++;                                           // the current thread is the newcomer
     336    if (b->waiting == b->expected) {                        //
     337        list_foreach (&b->wait, waiting_item) {             //
     338            list_unlink (waiting_item);                     //
     339            thread_t t = thread_item (waiting_item);        // get the pointer of a waiting thread
     340            thread_notify (t);                              //
     341        }
     342        b->waiting = 0;                                     //
     343        spin_unlock (&b->lock);                             //
     344    } else {
     345        thread_addlast (&b->wait, ThreadCurrent);           // the current thread in the wait. list
     346        spin_unlock (&b->lock);                             //
     347        thread_wait ();                                     //
     348
     349    return SUCCESS;                                         // it's fine
     350}