Changeset a3af522


Ignore:
Timestamp:
Nov 11, 2024, 10:32:08 PM (10 days ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
b5f1e850
Parents:
41882628
Message:

first attempt at updating barrier lock

File:
1 edited

Legend:

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

    r41882628 ra3af522  
    1 //
     1//                               -*- Mode: C -*-
     2//
    23// Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo
    3 //
     4// 
    45// The contents of this file are covered under the licence agreement in the
    56// file "LICENCE" distributed with Cforall.
    67//
    7 // barrier.hfa -- simple barrier implemented from monitors
    8 //
    9 // Author           : Thierry Delisle
    10 // Created On       : Thu Mar 31 16:51:35 2022
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     :
    14 //
     8// barrier.hfa -- simple barrier implemented using a monitor
     9// 
     10// Author           : Peter A. Buhr
     11// Created On       : Sun Nov 10 08:07:35 2024
     12// Last Modified By : Peter A. Buhr
     13// Last Modified On : Sun Nov 10 08:11:55 2024
     14// Update Count     : 3
     15// 
    1516
    1617#pragma once
     
    1819#include <monitor.hfa>
    1920
    20 // Simple barrier based on a monitor
     21// Plan 9 inheritance does not work with monitors. Two monitor locks are created.
     22
    2123monitor barrier {
    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;
    25 
    26         // Current count (counting backwards)
    27         unsigned count;
    28 
    29         // Barrier uses internal scheduling
    30         condition c;
     24        unsigned int group, arrivals;                                           // group size, arrival counter
     25        condition c;                                                                            // wait for group to form
    3126};
    3227
    3328// Constructor
    34 void ?{}( barrier & this, unsigned width ) {
    35         this.width = width;
    36         this.count = width; // Count backwards so initialize at width
     29void ?{}( barrier & b, unsigned group ) {
     30        b.group = b.arrivals = group;                                           // count backwards
    3731}
    3832
    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 // last is an optional hook that will be called by the last thread
    45 // before unblocking the others
    46 static inline unsigned block(barrier & mutex this, fptr_t last = (fptr_t)0 ) {
    47         this.count -= 1; // prefix decrement so we the last is 0 and not 1
    48         unsigned arrival = this.count; // Note arrival order
    49         if(arrival == 0) {
    50                 if(last) last();
    51                 // If arrived last unblock everyone and reset
    52                 signal_all(this.c);
    53                 this.count = this.width;
    54         } else {
    55                 // Otherwise block
    56                 wait(this.c);
    57         }
    58         return arrival; // return arrival order
     33// Returns a value indicating the reverse order the threads arrived i.e. last thread returns 0 (and does not block)
     34// last is an optional hook that is called by the last thread before unblocking the others.
     35static inline unsigned block( barrier & mutex b, fptr_t last = (fptr_t)0 ) with( b ) {
     36        arrivals -= 1;                                                                          // prefix decrement so last is 0 not 1
     37        unsigned arrived = b.arrivals;                                          // note arrival order
     38        if ( arrivals != 0 ) {                                                          // wait for group to form
     39                wait( b.c );
     40        } else {                                                                                        // group formed
     41                if ( last ) last();                                                             // safe to call
     42                signal_all( c );                                                                // unblock group
     43                arrivals = group;                                                               // reset
     44        } // if
     45        return arrived;                                                                         // return arrival order
    5946}
Note: See TracChangeset for help on using the changeset viewer.