Changeset 31ef267
- Timestamp:
- Apr 1, 2022, 12:40:35 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
- Children:
- 1417f6b
- Parents:
- 93b8cf4
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/barrier.hfa
r93b8cf4 r31ef267 18 18 #include <monitor.hfa> 19 19 20 // Simple barrier based on a monitor 20 21 monitor 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; 23 25 26 // Current count (counting backwards) 27 unsigned count; 28 29 // Barrier uses internal scheduling 24 30 condition c; 25 31 }; 26 32 27 void ?{}( barrier & this, int max ) { 28 this.max = max; 29 this.count = max; 33 // Constructor 34 void ?{}( barrier & this, unsigned width ) { 35 this.width = width; 36 this.count = width; // Count backwards so initialize at width 30 37 } 31 38 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. 44 static 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 36 53 wait(this.c); 37 } else {38 signal_all(this.c);39 this.count = this.max;40 54 } 41 return arrival; 55 return arrival; // return arrival order 42 56 } -
tests/concurrent/barrier/generation.cfa
r93b8cf4 r31ef267 15 15 // 16 16 17 // Test validates barrier by having each thread print ABCD... 18 // If the barrier is correct it should print all As, all Bs, etc. 17 19 18 intNUM_THREADS = 9;19 intNUM_LAPS = 53;20 unsigned NUM_THREADS = 9; 21 unsigned NUM_LAPS = 53; 20 22 21 23 #include <concurrency/barrier.hfa> … … 24 26 #include <thread.hfa> 25 27 28 // The barrier we are testing 26 29 barrier bar = { NUM_THREADS }; 30 27 31 28 32 thread Tester {}; 29 33 void main( Tester & this ) { 34 // Repeat the experiment a few times 30 35 for(NUM_LAPS) 36 // For each letters 31 37 for(c; 'A' ~= 'Z') { 38 // Yield for chaos 32 39 yield(prng(this, 10)); 40 41 // Print the generation, no newline because 33 42 mutex(sout) sout | c | nonl; 43 44 // Yield again for more chaos 34 45 yield(prng(this, 10)); 46 47 // Block on the barrier 35 48 block(bar); 36 49 } -
tests/concurrent/barrier/order.cfa
r93b8cf4 r31ef267 15 15 // 16 16 17 // Test validates barrier and block return value by checking 18 // that no more than one thread gets the same return value 19 17 20 #include <concurrency/barrier.hfa> 18 21 #include <fstream.hfa> … … 20 23 #include <thread.hfa> 21 24 22 const intNUM_LAPS = 173;23 const intNUM_THREADS = 11;25 const unsigned NUM_LAPS = 173; 26 const unsigned NUM_THREADS = 11; 24 27 28 // The barrier we are testing 25 29 barrier bar = { NUM_THREADS }; 26 volatile int * generation; 30 31 // The return values of the previous generation. 32 volatile unsigned * generation; 27 33 28 34 thread Tester {}; 29 35 void main( Tester & ) { 36 // Repeat a few times 30 37 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? 33 45 if(g != l) { 46 // Complain that they are different 34 47 sout | "Gen" | l | ": Expeced generation at" | ret | "to be" | l | "was" | g; 35 48 } 36 generation[ret] = g+1; 49 50 // Mark the expected next generation 51 generation[ret] = l+1; 37 52 } 38 53 } 39 54 40 55 int main() { 41 volatile int gen_data[NUM_THREADS]; 56 // Create the data ans zero it. 57 volatile unsigned gen_data[NUM_THREADS]; 42 58 for(t; NUM_THREADS) 43 59 gen_data[t] = 0; … … 45 61 generation = gen_data; 46 62 63 // Run the experiment 47 64 processor p[4]; 48 65 {
Note: See TracChangeset
for help on using the changeset viewer.