~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/sync/waitgroup.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
package sync
6
6
 
7
 
import "sync/atomic"
 
7
import (
 
8
        "sync/atomic"
 
9
        "unsafe"
 
10
)
8
11
 
9
12
// A WaitGroup waits for a collection of goroutines to finish.
10
13
// The main goroutine calls Add to set the number of
31
34
// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug.
32
35
 
33
36
// Add adds delta, which may be negative, to the WaitGroup counter.
34
 
// If the counter becomes zero, all goroutines blocked on Wait() are released.
 
37
// If the counter becomes zero, all goroutines blocked on Wait are released.
 
38
// If the counter goes negative, Add panics.
 
39
//
 
40
// Note that calls with positive delta must happen before the call to Wait,
 
41
// or else Wait may wait for too small a group. Typically this means the calls
 
42
// to Add should execute before the statement creating the goroutine or
 
43
// other event to be waited for. See the WaitGroup example.
35
44
func (wg *WaitGroup) Add(delta int) {
 
45
        if raceenabled {
 
46
                _ = wg.m.state
 
47
                raceReleaseMerge(unsafe.Pointer(wg))
 
48
                raceDisable()
 
49
                defer raceEnable()
 
50
        }
36
51
        v := atomic.AddInt32(&wg.counter, int32(delta))
37
52
        if v < 0 {
38
 
                panic("sync: negative WaitGroup count")
 
53
                panic("sync: negative WaitGroup counter")
39
54
        }
40
55
        if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
41
56
                return
56
71
 
57
72
// Wait blocks until the WaitGroup counter is zero.
58
73
func (wg *WaitGroup) Wait() {
 
74
        if raceenabled {
 
75
                _ = wg.m.state
 
76
                raceDisable()
 
77
        }
59
78
        if atomic.LoadInt32(&wg.counter) == 0 {
 
79
                if raceenabled {
 
80
                        raceEnable()
 
81
                        raceAcquire(unsafe.Pointer(wg))
 
82
                }
60
83
                return
61
84
        }
62
85
        wg.m.Lock()
67
90
        // to avoid missing an Add.
68
91
        if atomic.LoadInt32(&wg.counter) == 0 {
69
92
                atomic.AddInt32(&wg.waiters, -1)
 
93
                if raceenabled {
 
94
                        raceEnable()
 
95
                        raceAcquire(unsafe.Pointer(wg))
 
96
                        raceDisable()
 
97
                }
70
98
                wg.m.Unlock()
 
99
                if raceenabled {
 
100
                        raceEnable()
 
101
                }
71
102
                return
72
103
        }
73
104
        if wg.sema == nil {
76
107
        s := wg.sema
77
108
        wg.m.Unlock()
78
109
        runtime_Semacquire(s)
 
110
        if raceenabled {
 
111
                raceEnable()
 
112
                raceAcquire(unsafe.Pointer(wg))
 
113
        }
79
114
}