Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(37)

Delta Between Two Patch Sets: src/pkg/sync/cond.go

Issue 11573043: sync: faster Cond (Closed)
Left Patch Set: diff -r d7db8c804ffa https://dvyukov%40google.com@code.google.com/p/go/ Created 10 years, 7 months ago
Right Patch Set: diff -r ebf9b6a68289 https://dvyukov%40google.com@code.google.com/p/go/ Created 10 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/runtime/sema.goc ('k') | src/pkg/sync/cond_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package sync 5 package sync
6 6
7 import ( 7 import (
8 "sync/atomic" 8 "sync/atomic"
9 "unsafe" 9 "unsafe"
10 ) 10 )
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 c.L.Unlock() 61 c.L.Unlock()
62 runtime_Syncsemacquire(&c.sema) 62 runtime_Syncsemacquire(&c.sema)
63 c.L.Lock() 63 c.L.Lock()
64 } 64 }
65 65
66 // Signal wakes one goroutine waiting on c, if there is any. 66 // Signal wakes one goroutine waiting on c, if there is any.
67 // 67 //
68 // It is allowed but not required for the caller to hold c.L 68 // It is allowed but not required for the caller to hold c.L
69 // during the call. 69 // during the call.
70 func (c *Cond) Signal() { 70 func (c *Cond) Signal() {
71 » c.checker.check() 71 » c.signalImpl(false)
72 » if raceenabled {
73 » » raceDisable()
74 » }
75 » for {
76 » » w := atomic.LoadUint32(&c.waiters)
77 » » if w == 0 {
78 » » » if raceenabled {
79 » » » » raceEnable()
80 » » » }
81 » » » return
82 » » }
83 » » if atomic.CompareAndSwapUint32(&c.waiters, w, w-1) {
84 » » » if raceenabled {
85 » » » » raceEnable()
86 » » » }
87 » » » break
88 » » }
89 » }
90 » runtime_Syncsemrelease(&c.sema, 1)
91 } 72 }
92 73
93 // Broadcast wakes all goroutines waiting on c. 74 // Broadcast wakes all goroutines waiting on c.
94 // 75 //
95 // It is allowed but not required for the caller to hold c.L 76 // It is allowed but not required for the caller to hold c.L
96 // during the call. 77 // during the call.
97 func (c *Cond) Broadcast() { 78 func (c *Cond) Broadcast() {
79 c.signalImpl(true)
80 }
81
82 func (c *Cond) signalImpl(all bool) {
98 c.checker.check() 83 c.checker.check()
99 if raceenabled { 84 if raceenabled {
100 raceDisable() 85 raceDisable()
101 } 86 }
102 var w uint32
103 for { 87 for {
104 » » w = atomic.LoadUint32(&c.waiters) 88 » » old := atomic.LoadUint32(&c.waiters)
105 » » if w == 0 { 89 » » if old == 0 {
106 if raceenabled { 90 if raceenabled {
107 raceEnable() 91 raceEnable()
108 } 92 }
109 return 93 return
110 } 94 }
111 » » if atomic.CompareAndSwapUint32(&c.waiters, w, 0) { 95 » » new := old - 1
96 » » if all {
97 » » » new = 0
98 » » }
99 » » if atomic.CompareAndSwapUint32(&c.waiters, old, new) {
112 if raceenabled { 100 if raceenabled {
113 raceEnable() 101 raceEnable()
114 } 102 }
115 » » » break 103 » » » runtime_Syncsemrelease(&c.sema, old-new)
104 » » » return
116 } 105 }
117 } 106 }
118 runtime_Syncsemrelease(&c.sema, w)
119 } 107 }
120 108
121 // copyChecker holds back pointer to itself to detect object copying. 109 // copyChecker holds back pointer to itself to detect object copying.
122 type copyChecker uintptr 110 type copyChecker uintptr
123 111
124 func (c *copyChecker) check() { 112 func (c *copyChecker) check() {
125 println("check", c, *c)
126 if uintptr(*c) != uintptr(unsafe.Pointer(c)) && 113 if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
127 !atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.P ointer(c))) && 114 !atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.P ointer(c))) &&
128 uintptr(*c) != uintptr(unsafe.Pointer(c)) { 115 uintptr(*c) != uintptr(unsafe.Pointer(c)) {
129 panic("sync.Cond is copied") 116 panic("sync.Cond is copied")
130 } 117 }
131 } 118 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b