Changeset 31ef267


Ignore:
Timestamp:
Apr 1, 2022, 12:40:35 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
1417f6b
Parents:
93b8cf4
Message:

Added comments.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/barrier.hfa

    r93b8cf4 r31ef267  
    1818#include <monitor.hfa>
    1919
     20// Simple barrier based on a monitor
    2021monitor barrier {
    21         int max;
    22         int count;
     22        // Number of threads blocking needed to unblock the barrier
     23        // Unsigned should be enough, I don't expect use cases with 2^32 thread barriers.
     24        unsigned width;
    2325
     26        // Current count (counting backwards)
     27        unsigned count;
     28
     29        // Barrier uses internal scheduling
    2430        condition c;
    2531};
    2632
    27 void ?{}( barrier & this, int max ) {
    28         this.max = max;
    29         this.count = max;
     33// Constructor
     34void ?{}( barrier & this, unsigned width ) {
     35        this.width = width;
     36        this.count = width; // Count backwards so initialize at width
    3037}
    3138
    32 static inline int block(barrier & mutex this ) {
    33         this.count -= 1;
    34         int arrival = this.count;
    35         if(arrival != 0) {
     39// block until the number of threads needed have blocked
     40// returns an value indicating the reverse order the threads arrived in
     41// i.e. last thread will return 0 (and not block)
     42//      second last thread returns 1
     43//      etc.
     44static inline unsigned block(barrier & mutex this ) {
     45        this.count -= 1; // prefix decrement so we the last is 0 and not 1
     46        unsigned arrival = this.count; // Note arrival order
     47        if(arrival == 0) {
     48                // If arrived last unblock everyone and reset
     49                signal_all(this.c);
     50                this.count = this.width;
     51        } else {
     52                // Otherwise block
    3653                wait(this.c);
    37         } else {
    38                 signal_all(this.c);
    39                 this.count = this.max;
    4054        }
    41         return arrival;
     55        return arrival; // return arrival order
    4256}
  • tests/concurrent/barrier/generation.cfa

    r93b8cf4 r31ef267  
    1515//
    1616
     17// Test validates barrier by having each thread print ABCD...
     18// If the barrier is correct it should print all As, all Bs, etc.
    1719
    18 int NUM_THREADS = 9;
    19 int NUM_LAPS = 53;
     20unsigned NUM_THREADS = 9;
     21unsigned NUM_LAPS = 53;
    2022
    2123#include <concurrency/barrier.hfa>
     
    2426#include <thread.hfa>
    2527
     28// The barrier we are testing
    2629barrier bar = { NUM_THREADS };
     30
    2731
    2832thread Tester {};
    2933void main( Tester & this ) {
     34        // Repeat the experiment a few times
    3035        for(NUM_LAPS)
     36                // For each letters
    3137                for(c; 'A' ~= 'Z') {
     38                        // Yield for chaos
    3239                        yield(prng(this, 10));
     40
     41                        // Print the generation, no newline because
    3342                        mutex(sout) sout | c | nonl;
     43
     44                        // Yield again for more chaos
    3445                        yield(prng(this, 10));
     46
     47                        // Block on the barrier
    3548                        block(bar);
    3649                }
  • tests/concurrent/barrier/order.cfa

    r93b8cf4 r31ef267  
    1515//
    1616
     17// Test validates barrier and block return value by checking
     18// that no more than one thread gets the same return value
     19
    1720#include <concurrency/barrier.hfa>
    1821#include <fstream.hfa>
     
    2023#include <thread.hfa>
    2124
    22 const int NUM_LAPS = 173;
    23 const int NUM_THREADS = 11;
     25const unsigned NUM_LAPS = 173;
     26const unsigned NUM_THREADS = 11;
    2427
     28// The barrier we are testing
    2529barrier bar = { NUM_THREADS };
    26 volatile int * generation;
     30
     31// The return values of the previous generation.
     32volatile unsigned * generation;
    2733
    2834thread Tester {};
    2935void main( Tester & ) {
     36        // Repeat a few times
    3037        for(l; NUM_LAPS) {
    31                 int ret = block(bar);
    32                 int g = generation[ret];
     38                // Block and what order we arrived
     39                unsigned ret = block(bar);
     40
     41                // Check what was the last generation of that last thread in this position
     42                unsigned g = generation[ret];
     43
     44                // Is it what we expect?
    3345                if(g != l) {
     46                        // Complain that they are different
    3447                        sout | "Gen" | l | ": Expeced generation at" | ret | "to be" | l | "was" | g;
    3548                }
    36                 generation[ret] = g+1;
     49
     50                // Mark the expected next generation
     51                generation[ret] = l+1;
    3752        }
    3853}
    3954
    4055int main() {
    41         volatile int gen_data[NUM_THREADS];
     56        // Create the data ans zero it.
     57        volatile unsigned gen_data[NUM_THREADS];
    4258        for(t; NUM_THREADS)
    4359                gen_data[t] = 0;
     
    4561        generation = gen_data;
    4662
     63        // Run the experiment
    4764        processor p[4];
    4865        {
Note: See TracChangeset for help on using the changeset viewer.