Merge release-20200115.0-68-gd0e75f2 (automated)
This commit is contained in:
commit
4450d973d9
|
@ -19,7 +19,6 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -30,18 +29,43 @@ func runtimeSemacquire(s *uint32)
|
|||
//go:linkname runtimeSemrelease sync.runtime_Semrelease
|
||||
func runtimeSemrelease(s *uint32, handoff bool, skipframes int)
|
||||
|
||||
// DowngradableRWMutex is identical to sync.RWMutex, but adds the DowngradeLock
|
||||
// method.
|
||||
// DowngradableRWMutex is identical to sync.RWMutex, but adds the DowngradeLock,
|
||||
// TryLock and TryRLock methods.
|
||||
type DowngradableRWMutex struct {
|
||||
w sync.Mutex // held if there are pending writers
|
||||
writerSem uint32 // semaphore for writers to wait for completing readers
|
||||
readerSem uint32 // semaphore for readers to wait for completing writers
|
||||
readerCount int32 // number of pending readers
|
||||
readerWait int32 // number of departing readers
|
||||
w TMutex // held if there are pending writers
|
||||
writerSem uint32 // semaphore for writers to wait for completing readers
|
||||
readerSem uint32 // semaphore for readers to wait for completing writers
|
||||
readerCount int32 // number of pending readers
|
||||
readerWait int32 // number of departing readers
|
||||
}
|
||||
|
||||
const rwmutexMaxReaders = 1 << 30
|
||||
|
||||
// TryRLock locks rw for reading. It returns true if it succeeds and false
|
||||
// otherwise. It does not block.
|
||||
func (rw *DowngradableRWMutex) TryRLock() bool {
|
||||
if RaceEnabled {
|
||||
RaceDisable()
|
||||
}
|
||||
for {
|
||||
rc := atomic.LoadInt32(&rw.readerCount)
|
||||
if rc < 0 {
|
||||
if RaceEnabled {
|
||||
RaceEnable()
|
||||
}
|
||||
return false
|
||||
}
|
||||
if !atomic.CompareAndSwapInt32(&rw.readerCount, rc, rc+1) {
|
||||
continue
|
||||
}
|
||||
if RaceEnabled {
|
||||
RaceEnable()
|
||||
RaceAcquire(unsafe.Pointer(&rw.readerSem))
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// RLock locks rw for reading.
|
||||
func (rw *DowngradableRWMutex) RLock() {
|
||||
if RaceEnabled {
|
||||
|
@ -78,6 +102,34 @@ func (rw *DowngradableRWMutex) RUnlock() {
|
|||
}
|
||||
}
|
||||
|
||||
// TryLock locks rw for writing. It returns true if it succeeds and false
|
||||
// otherwise. It does not block.
|
||||
func (rw *DowngradableRWMutex) TryLock() bool {
|
||||
if RaceEnabled {
|
||||
RaceDisable()
|
||||
}
|
||||
// First, resolve competition with other writers.
|
||||
if !rw.w.TryLock() {
|
||||
if RaceEnabled {
|
||||
RaceEnable()
|
||||
}
|
||||
return false
|
||||
}
|
||||
// Only proceed if there are no readers.
|
||||
if !atomic.CompareAndSwapInt32(&rw.readerCount, 0, -rwmutexMaxReaders) {
|
||||
rw.w.Unlock()
|
||||
if RaceEnabled {
|
||||
RaceEnable()
|
||||
}
|
||||
return false
|
||||
}
|
||||
if RaceEnabled {
|
||||
RaceEnable()
|
||||
RaceAcquire(unsafe.Pointer(&rw.writerSem))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Lock locks rw for writing.
|
||||
func (rw *DowngradableRWMutex) Lock() {
|
||||
if RaceEnabled {
|
||||
|
|
Loading…
Reference in New Issue