//
// 不要在Rlock内设置变量,有DATA RACE风险
func (m *RWMutex) RLock(to ...time.Duration) (unlockf func()) {
- _, rlcLoop := lcas(&m.rlc, ulock, rlock)
- if e := rlcLoop(to...); e != nil {
- panic(e)
+ if m.read.Add(1) == 1 {
+ _, rlcLoop := cas(&m.rlc, ulock, rlock)
+ if e := rlcLoop(to...); e != nil {
+ panic(e)
+ }
+ } else {
+ _, rlcLoop := lcas(&m.rlc, ulock, rlock)
+ if e := rlcLoop(to...); e != nil {
+ panic(e)
+ }
}
- m.read.Add(1)
var callC atomic.Bool
var done func() (called bool)
if len(to) > 1 {
}
}
+func Test0(t *testing.T) {
+ var l RWMutex
+ ul := l.RLock()
+ go func() {
+ l.Lock()()
+ }()
+ go func() {
+ l.RLock()()
+ }()
+ ul()
+}
+
// ulock rlock rlock
func Test1(t *testing.T) {
var l RWMutex
ul := l.Lock()
check(&l, lock, 0)
time.AfterFunc(time.Second, func() {
- check(&l, lock, 0)
+ check(&l, lock, 1)
ul()
})
c := time.Now()
check(&l, ulock, 0)
}
-// ulock lock rlock
-func Test6(t *testing.T) {
- var l RWMutex
- ul := l.Lock()
- check(&l, lock, 0)
- time.AfterFunc(time.Second, func() {
- check(&l, lock, 0)
- ul()
- })
- c := time.Now()
- ul1 := l.RLock()
- check(&l, rlock, 1)
- if time.Since(c) < time.Second {
- t.Fail()
- }
- ul1()
- check(&l, ulock, 0)
-}
-
func BenchmarkRlock(b *testing.B) {
var lock1 RWMutex
var a bool