-
Notifications
You must be signed in to change notification settings - Fork 0
/
barrier.go
42 lines (38 loc) · 1.11 KB
/
barrier.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package barrier
import (
"sync"
)
// A Barrier is a synchronization mechanism for groups of worker goroutines.
// Barriers are used to synchronize that group of goroutines to different points
// in a parallel algorithm. For example, many goroutines may be assigned
// ownership of parts of an array or slice for updating in parallel, and another
// goroutine may wish to synchronize across the entire group to get the results.
//
// For a more flexible interface you can use WaitGroup from the standard Go sync
// package.
type Barrier struct {
n int
l *sync.Mutex
waiter *sync.RWMutex
}
// NewBarrier creates a new barrier of size n. Subsequent calls to Wait will
// block all goroutines that have called it until Wait is called n times.
func NewBarrier(n int) *Barrier {
if n <= 0 {
panic("Group must be >= 1")
}
waiter := &sync.RWMutex{}
waiter.Lock()
return &Barrier{n, &sync.Mutex{}, waiter}
}
// Wait blocks until all the members of the group (size n from NewBarrier) have
// "checked in".
func (b *Barrier) Wait() {
b.l.Lock()
b.n--
if b.n == 0 {
b.waiter.Unlock()
}
b.l.Unlock()
b.waiter.RLock()
}