aboutsummaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorCarlo Alberto Ferraris <cafxx@strayorange.com>2018-11-09 22:49:38 +0900
committerBrad Fitzpatrick <bradfitz@golang.org>2019-03-09 05:08:04 +0000
commit41cb0aedffdf4c5087de82710c4d016a3634b4ac (patch)
treef0c772a063246ab13b3fdf59c61e7dd2ee531c5d /src/sync
parent83a33d3855e257b383b2a3a10dfd9748ad17cfb4 (diff)
downloadgo-41cb0aedffdf4c5087de82710c4d016a3634b4ac.tar.gz
go-41cb0aedffdf4c5087de82710c4d016a3634b4ac.zip
sync: allow inlining the Mutex.Lock fast path
name old time/op new time/op delta MutexUncontended 18.9ns ± 0% 16.2ns ± 0% -14.29% (p=0.000 n=19+19) MutexUncontended-4 4.75ns ± 1% 4.08ns ± 0% -14.20% (p=0.000 n=20+19) MutexUncontended-16 2.05ns ± 0% 2.11ns ± 0% +2.93% (p=0.000 n=19+16) Mutex 19.3ns ± 1% 16.2ns ± 0% -15.86% (p=0.000 n=17+19) Mutex-4 52.4ns ± 4% 48.6ns ± 9% -7.22% (p=0.000 n=20+20) Mutex-16 139ns ± 2% 140ns ± 3% +1.03% (p=0.011 n=16+20) MutexSlack 18.9ns ± 1% 16.2ns ± 1% -13.96% (p=0.000 n=20+20) MutexSlack-4 225ns ± 8% 211ns ±10% -5.94% (p=0.000 n=18+19) MutexSlack-16 98.4ns ± 1% 90.9ns ± 1% -7.60% (p=0.000 n=17+18) MutexWork 58.2ns ± 3% 55.4ns ± 0% -4.82% (p=0.000 n=20+17) MutexWork-4 103ns ± 7% 95ns ±18% -8.03% (p=0.000 n=20+20) MutexWork-16 163ns ± 2% 155ns ± 2% -4.47% (p=0.000 n=18+18) MutexWorkSlack 57.7ns ± 1% 55.4ns ± 0% -3.99% (p=0.000 n=20+13) MutexWorkSlack-4 276ns ±13% 260ns ±10% -5.64% (p=0.001 n=19+19) MutexWorkSlack-16 147ns ± 0% 156ns ± 1% +5.87% (p=0.000 n=14+19) MutexNoSpin 968ns ± 0% 900ns ± 1% -6.98% (p=0.000 n=20+18) MutexNoSpin-4 270ns ± 2% 255ns ± 2% -5.74% (p=0.000 n=19+20) MutexNoSpin-16 120ns ± 4% 112ns ± 0% -6.99% (p=0.000 n=19+14) MutexSpin 3.13µs ± 1% 3.19µs ± 6% ~ (p=0.401 n=20+20) MutexSpin-4 832ns ± 2% 831ns ± 1% -0.17% (p=0.023 n=16+18) MutexSpin-16 395ns ± 0% 399ns ± 0% +0.94% (p=0.000 n=17+19) RWMutexUncontended 69.5ns ± 0% 68.4ns ± 0% -1.59% (p=0.000 n=20+20) RWMutexUncontended-4 17.5ns ± 0% 16.7ns ± 0% -4.30% (p=0.000 n=18+17) RWMutexUncontended-16 7.92ns ± 0% 7.87ns ± 0% -0.61% (p=0.000 n=18+17) RWMutexWrite100 24.9ns ± 1% 25.0ns ± 1% +0.32% (p=0.000 n=20+20) RWMutexWrite100-4 46.2ns ± 4% 46.2ns ± 5% ~ (p=0.840 n=19+20) RWMutexWrite100-16 69.9ns ± 5% 69.9ns ± 3% ~ (p=0.545 n=20+19) RWMutexWrite10 27.0ns ± 2% 26.8ns ± 2% -0.98% (p=0.001 n=20+20) RWMutexWrite10-4 34.7ns ± 2% 35.0ns ± 4% ~ (p=0.191 n=18+20) RWMutexWrite10-16 37.2ns ± 4% 37.3ns ± 2% ~ (p=0.438 n=20+19) RWMutexWorkWrite100 164ns ± 0% 163ns ± 0% -0.24% (p=0.025 n=20+20) RWMutexWorkWrite100-4 193ns ± 3% 191ns ± 2% -1.06% (p=0.027 n=20+20) RWMutexWorkWrite100-16 210ns ± 3% 207ns ± 3% -1.22% (p=0.038 n=20+20) RWMutexWorkWrite10 153ns ± 0% 153ns ± 0% ~ (all equal) RWMutexWorkWrite10-4 178ns ± 2% 179ns ± 2% ~ (p=0.186 n=20+20) RWMutexWorkWrite10-16 192ns ± 2% 192ns ± 2% ~ (p=0.731 n=19+20) linux/amd64 bin/go 14663387 (previous commit 14630572, +32815/+0.22%) Change-Id: I98171006dce14069b1a62da07c3d165455a7906b Reviewed-on: https://go-review.googlesource.com/c/go/+/148959 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/sync')
-rw-r--r--src/sync/mutex.go6
-rw-r--r--src/sync/runtime.go4
-rw-r--r--src/sync/rwmutex.go4
3 files changed, 10 insertions, 4 deletions
diff --git a/src/sync/mutex.go b/src/sync/mutex.go
index a809993fe0..11ad20c975 100644
--- a/src/sync/mutex.go
+++ b/src/sync/mutex.go
@@ -77,7 +77,11 @@ func (m *Mutex) Lock() {
}
return
}
+ // Slow path (outlined so that the fast path can be inlined)
+ m.lockSlow()
+}
+func (m *Mutex) lockSlow() {
var waitStartTime int64
starving := false
awoke := false
@@ -131,7 +135,7 @@ func (m *Mutex) Lock() {
if waitStartTime == 0 {
waitStartTime = runtime_nanotime()
}
- runtime_SemacquireMutex(&m.sema, queueLifo)
+ runtime_SemacquireMutex(&m.sema, queueLifo, 1)
starving = starving || runtime_nanotime()-waitStartTime > starvationThresholdNs
old = m.state
if old&mutexStarving != 0 {
diff --git a/src/sync/runtime.go b/src/sync/runtime.go
index 8b20b0f6f7..3ad44e786f 100644
--- a/src/sync/runtime.go
+++ b/src/sync/runtime.go
@@ -15,7 +15,9 @@ func runtime_Semacquire(s *uint32)
// SemacquireMutex is like Semacquire, but for profiling contended Mutexes.
// If lifo is true, queue waiter at the head of wait queue.
-func runtime_SemacquireMutex(s *uint32, lifo bool)
+// skipframes is the number of frames to omit during tracing, counting from
+// runtime_SemacquireMutex's caller.
+func runtime_SemacquireMutex(s *uint32, lifo bool, skipframes int)
// Semrelease atomically increments *s and notifies a waiting goroutine
// if one is blocked in Semacquire.
diff --git a/src/sync/rwmutex.go b/src/sync/rwmutex.go
index 24dd78cbe7..aafd6a7010 100644
--- a/src/sync/rwmutex.go
+++ b/src/sync/rwmutex.go
@@ -47,7 +47,7 @@ func (rw *RWMutex) RLock() {
}
if atomic.AddInt32(&rw.readerCount, 1) < 0 {
// A writer is pending, wait for it.
- runtime_SemacquireMutex(&rw.readerSem, false)
+ runtime_SemacquireMutex(&rw.readerSem, false, 0)
}
if race.Enabled {
race.Enable()
@@ -95,7 +95,7 @@ func (rw *RWMutex) Lock() {
r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
- runtime_SemacquireMutex(&rw.writerSem, false)
+ runtime_SemacquireMutex(&rw.writerSem, false, 0)
}
if race.Enabled {
race.Enable()