From f3896a9ba7c5b6ca62a1e292aa85ee482af6f51d Mon Sep 17 00:00:00 2001 From: qydysky Date: Sun, 14 Jan 2024 18:28:23 +0800 Subject: [PATCH] 1 --- msgq/Msgq.go | 3 +- msgq/Msgq_test.go | 12 ++------ sync/RWMutex.go | 31 ++++++++----------- sync/RWMutex_test.go | 73 ++++++++++++++++++++++++++++---------------- 4 files changed, 61 insertions(+), 58 deletions(-) diff --git a/msgq/Msgq.go b/msgq/Msgq.go index 07f1583..bb75998 100644 --- a/msgq/Msgq.go +++ b/msgq/Msgq.go @@ -168,8 +168,7 @@ func (m *Msgq) Push_tag(Tag string, Data any) { Data: Data, }) */ - ul := m.lock.RLock(m.to...) - defer ul(m.removeDisable) + defer m.lock.RLock(m.to...)(m.removeDisable) for el := m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) diff --git a/msgq/Msgq_test.go b/msgq/Msgq_test.go index b00ca07..3d5102c 100644 --- a/msgq/Msgq_test.go +++ b/msgq/Msgq_test.go @@ -437,24 +437,19 @@ func Test_msgq3(t *testing.T) { func Test_msgq4(t *testing.T) { // mq := New(30) - mq := New() //out of list + mq := New(time.Second, time.Second) //out of list - mun_c1 := make(chan bool, 100) - mun_c2 := make(chan bool, 100) - mun_c3 := make(chan bool, 100) mq.Pull_tag(map[string]func(any) bool{ `A1`: func(data any) bool { if v, ok := data.(string); !ok || v != `a11` { t.Error(`1`) } - mun_c1 <- true return false }, `A2`: func(data any) bool { if v, ok := data.(string); !ok || v != `a11` { t.Error(`2`) } - mun_c2 <- true return false }, `Error`: func(data any) bool { @@ -469,7 +464,6 @@ func Test_msgq4(t *testing.T) { if v, ok := data.(string); !ok || v != `a11` { t.Error(`2`) } - mun_c3 <- true return false }, `Error`: func(data any) bool { @@ -482,7 +476,7 @@ func Test_msgq4(t *testing.T) { var fin_turn = 0 time.Sleep(time.Second) - for fin_turn < 5 { + for fin_turn < 20 { go mq.Push_tag(`A1`, `a11`) go mq.Push_tag(`A1`, `a11`) go mq.Push_tag(`A1`, `a11`) @@ -491,8 +485,6 @@ func Test_msgq4(t *testing.T) { mq.Push_tag(`A1`, `a11`) mq.Push_tag(`A2`, `a11`) // mq.Push_tag(`A4`,`a11`) - <-mun_c2 - <-mun_c1 // <-mun_c3 fin_turn += 1 } diff --git a/sync/RWMutex.go b/sync/RWMutex.go index a0f0836..9f787c2 100644 --- a/sync/RWMutex.go +++ b/sync/RWMutex.go @@ -5,15 +5,15 @@ import ( "fmt" "runtime" "strings" - "sync/atomic" + "sync" "time" ) -const ( - lock int32 = -1 - ulock int32 = 0 - rlock int32 = 1 -) +// const ( +// lock int32 = -1 +// ulock int32 = 0 +// rlock int32 = 1 +// ) var ( ErrTimeoutToLock = errors.New("ErrTimeoutToLock") @@ -21,7 +21,7 @@ var ( ) type RWMutex struct { - rlc atomic.Int32 + rlc sync.RWMutex PanicFunc func(any) } @@ -91,11 +91,7 @@ func (m *RWMutex) RLock(to ...time.Duration) (unlockf func(beforeUlock ...func() defer m.tof(to[0], ErrTimeoutToLock)() } - for m.rlc.Load() < rlock && !m.rlc.CompareAndSwap(ulock, rlock) { - runtime.Gosched() - } - - m.rlc.Add(1) + m.rlc.RLock() return func(beforeUlock ...func()) { if len(to) > 1 { @@ -104,9 +100,7 @@ func (m *RWMutex) RLock(to ...time.Duration) (unlockf func(beforeUlock ...func() for i := 0; i < len(beforeUlock); i++ { beforeUlock[i]() } - if m.rlc.Add(-1) == rlock { - m.rlc.CompareAndSwap(rlock, ulock) - } + m.rlc.RUnlock() } } @@ -117,9 +111,8 @@ func (m *RWMutex) Lock(to ...time.Duration) (unlockf func(beforeUlock ...func()) if len(to) > 0 { defer m.tof(to[0], ErrTimeoutToLock)() } - for !m.rlc.CompareAndSwap(ulock, lock) { - runtime.Gosched() - } + + m.rlc.Lock() return func(beforeUlock ...func()) { if len(to) > 1 { @@ -128,7 +121,7 @@ func (m *RWMutex) Lock(to ...time.Duration) (unlockf func(beforeUlock ...func()) for i := 0; i < len(beforeUlock); i++ { beforeUlock[i]() } - m.rlc.Store(ulock) + m.rlc.Unlock() } } diff --git a/sync/RWMutex_test.go b/sync/RWMutex_test.go index 91c530a..fb56fbd 100644 --- a/sync/RWMutex_test.go +++ b/sync/RWMutex_test.go @@ -2,15 +2,15 @@ package part import ( "errors" - "fmt" + "sync" "testing" "time" ) func check(l *RWMutex, r int32) { - if i := l.rlc.Load(); i != r { - panic(fmt.Errorf("%v %v", i, r)) - } + // if i := l.rlc.Load(); i != r { + // panic(fmt.Errorf("%v %v", i, r)) + // } } func Test0(t *testing.T) { @@ -28,15 +28,15 @@ func Test0(t *testing.T) { // ulock rlock rlock func Test1(t *testing.T) { var l RWMutex - check(&l, 0) + //check(&l, 0) ul := l.RLock() - check(&l, 2) + //check(&l, 2) ul1 := l.RLock() - check(&l, 3) + //check(&l, 3) ul() - check(&l, 2) + //check(&l, 2) ul1() - check(&l, 0) + //check(&l, 0) } func Test4(t *testing.T) { @@ -76,38 +76,38 @@ func Test8(t *testing.T) { func Test2(t *testing.T) { var l RWMutex ul := l.RLock() - check(&l, 2) + //check(&l, 2) time.AfterFunc(time.Second, func() { - check(&l, 2) + //check(&l, 2) ul() }) c := time.Now() ul1 := l.Lock() - check(&l, -1) + //check(&l, -1) if time.Since(c) < time.Second { t.Fail() } ul1() - check(&l, 0) + //check(&l, 0) } // ulock lock rlock func Test3(t *testing.T) { var l RWMutex ul := l.Lock() - check(&l, -1) + //check(&l, -1) time.AfterFunc(time.Second, func() { - check(&l, -1) + //check(&l, -1) ul() }) c := time.Now() ul1 := l.RLock() - check(&l, 2) + //check(&l, 2) if time.Since(c) < time.Second { t.Fail() } ul1() - check(&l, 0) + //check(&l, 0) } func Test6(t *testing.T) { @@ -154,6 +154,25 @@ func Test7(t *testing.T) { } } +func Test9(t *testing.T) { + n := time.Now() + var l RWMutex + for i := 0; i < 1000; i++ { + go l.RLock(time.Second, time.Second)() + } + t.Log(time.Since(n)) +} + +func Test10(t *testing.T) { + n := time.Now() + var l sync.RWMutex + for i := 0; i < 300; i++ { + l.RLock() + go l.RUnlock() + } + t.Log(time.Since(n)) +} + func Panic_Test8(t *testing.T) { var l RWMutex ul := l.Lock(time.Second, time.Second) @@ -165,16 +184,16 @@ func Panic_Test8(t *testing.T) { // ulock rlock rlock func Panic_Test4(t *testing.T) { var l RWMutex - check(&l, 0) + //check(&l, 0) ul := l.RLock(time.Second, time.Second) - check(&l, 1) + //check(&l, 1) ul1 := l.RLock(time.Second, time.Second) - check(&l, 2) + //check(&l, 2) time.Sleep(time.Millisecond * 1500) ul() - check(&l, 1) + //check(&l, 1) ul1() - check(&l, 0) + //check(&l, 0) time.Sleep(time.Second * 3) } @@ -182,19 +201,19 @@ func Panic_Test4(t *testing.T) { func Panic_Test5(t *testing.T) { var l RWMutex ul := l.RLock() - check(&l, 1) + //check(&l, 1) time.AfterFunc(time.Millisecond*1500, func() { - check(&l, 1) + //check(&l, 1) ul() }) c := time.Now() ul1 := l.Lock(time.Second) - check(&l, 0) + //check(&l, 0) if time.Since(c) < time.Second { t.Fail() } ul1() - check(&l, 0) + //check(&l, 0) } /* @@ -212,6 +231,6 @@ PASS func BenchmarkRlock(b *testing.B) { var lock1 RWMutex for i := 0; i < b.N; i++ { - lock1.Lock()() + lock1.RLock()() } } -- 2.39.2