URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [sync/] [rwmutex.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package syncimport ("runtime""sync/atomic")// An RWMutex is a reader/writer mutual exclusion lock.// The lock can be held by an arbitrary number of readers// or a single writer.// RWMutexes can be created as part of other// structures; the zero value for a RWMutex is// an unlocked mutex.type RWMutex struct {w Mutex // held if there are pending writerswriterSem uint32 // semaphore for writers to wait for completing readersreaderSem uint32 // semaphore for readers to wait for completing writersreaderCount int32 // number of pending readersreaderWait int32 // number of departing readers}const rwmutexMaxReaders = 1 << 30// RLock locks rw for reading.func (rw *RWMutex) RLock() {if atomic.AddInt32(&rw.readerCount, 1) < 0 {// A writer is pending, wait for it.runtime.Semacquire(&rw.readerSem)}}// RUnlock undoes a single RLock call;// it does not affect other simultaneous readers.// It is a run-time error if rw is not locked for reading// on entry to RUnlock.func (rw *RWMutex) RUnlock() {if atomic.AddInt32(&rw.readerCount, -1) < 0 {// A writer is pending.if atomic.AddInt32(&rw.readerWait, -1) == 0 {// The last reader unblocks the writer.runtime.Semrelease(&rw.writerSem)}}}// Lock locks rw for writing.// If the lock is already locked for reading or writing,// Lock blocks until the lock is available.// To ensure that the lock eventually becomes available,// a blocked Lock call excludes new readers from acquiring// the lock.func (rw *RWMutex) Lock() {// First, resolve competition with other writers.rw.w.Lock()// Announce to readers there is a pending writer.r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders// Wait for active readers.if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {runtime.Semacquire(&rw.writerSem)}}// Unlock unlocks rw for writing. It is a run-time error if rw is// not locked for writing on entry to Unlock.//// As with Mutexes, a locked RWMutex is not associated with a particular// goroutine. One goroutine may RLock (Lock) an RWMutex and then// arrange for another goroutine to RUnlock (Unlock) it.func (rw *RWMutex) Unlock() {// Announce to readers there is no active writer.r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)// Unblock blocked readers, if any.for i := 0; i < int(r); i++ {runtime.Semrelease(&rw.readerSem)}// Allow other writers to proceed.rw.w.Unlock()}// RLocker returns a Locker interface that implements// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.func (rw *RWMutex) RLocker() Locker {return (*rlocker)(rw)}type rlocker RWMutexfunc (r *rlocker) Lock() { (*RWMutex)(r).RLock() }func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
