...
Source file src/pkg/sync/rwmutex.go
1
2
3
4
5 package sync
6
7 import (
8 "internal/race"
9 "sync/atomic"
10 "unsafe"
11 )
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 type RWMutex struct {
29 w Mutex
30 writerSem uint32
31 readerSem uint32
32 readerCount int32
33 readerWait int32
34 }
35
36 const rwmutexMaxReaders = 1 << 30
37
38
39
40
41
42
43 func (rw *RWMutex) RLock() {
44 if race.Enabled {
45 _ = rw.w.state
46 race.Disable()
47 }
48 if atomic.AddInt32(&rw.readerCount, 1) < 0 {
49
50 runtime_SemacquireMutex(&rw.readerSem, false, 0)
51 }
52 if race.Enabled {
53 race.Enable()
54 race.Acquire(unsafe.Pointer(&rw.readerSem))
55 }
56 }
57
58
59
60
61
62 func (rw *RWMutex) RUnlock() {
63 if race.Enabled {
64 _ = rw.w.state
65 race.ReleaseMerge(unsafe.Pointer(&rw.writerSem))
66 race.Disable()
67 }
68 if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 {
69
70 rw.rUnlockSlow(r)
71 }
72 if race.Enabled {
73 race.Enable()
74 }
75 }
76
77 func (rw *RWMutex) rUnlockSlow(r int32) {
78 if r+1 == 0 || r+1 == -rwmutexMaxReaders {
79 race.Enable()
80 throw("sync: RUnlock of unlocked RWMutex")
81 }
82
83 if atomic.AddInt32(&rw.readerWait, -1) == 0 {
84
85 runtime_Semrelease(&rw.writerSem, false, 1)
86 }
87 }
88
89
90
91
92 func (rw *RWMutex) Lock() {
93 if race.Enabled {
94 _ = rw.w.state
95 race.Disable()
96 }
97
98 rw.w.Lock()
99
100 r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
101
102 if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
103 runtime_SemacquireMutex(&rw.writerSem, false, 0)
104 }
105 if race.Enabled {
106 race.Enable()
107 race.Acquire(unsafe.Pointer(&rw.readerSem))
108 race.Acquire(unsafe.Pointer(&rw.writerSem))
109 }
110 }
111
112
113
114
115
116
117
118 func (rw *RWMutex) Unlock() {
119 if race.Enabled {
120 _ = rw.w.state
121 race.Release(unsafe.Pointer(&rw.readerSem))
122 race.Disable()
123 }
124
125
126 r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)
127 if r >= rwmutexMaxReaders {
128 race.Enable()
129 throw("sync: Unlock of unlocked RWMutex")
130 }
131
132 for i := 0; i < int(r); i++ {
133 runtime_Semrelease(&rw.readerSem, false, 0)
134 }
135
136 rw.w.Unlock()
137 if race.Enabled {
138 race.Enable()
139 }
140 }
141
142
143
144 func (rw *RWMutex) RLocker() Locker {
145 return (*rlocker)(rw)
146 }
147
148 type rlocker RWMutex
149
150 func (r *rlocker) Lock() { (*RWMutex)(r).RLock() }
151 func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
152
View as plain text