diff options
Diffstat (limited to 'src/pkg/sync/mutex.go')
-rw-r--r-- | src/pkg/sync/mutex.go | 109 |
1 files changed, 0 insertions, 109 deletions
diff --git a/src/pkg/sync/mutex.go b/src/pkg/sync/mutex.go deleted file mode 100644 index 73b337702..000000000 --- a/src/pkg/sync/mutex.go +++ /dev/null @@ -1,109 +0,0 @@ -// 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 sync provides basic synchronization primitives such as mutual -// exclusion locks. Other than the Once and WaitGroup types, most are intended -// for use by low-level library routines. Higher-level synchronization is -// better done via channels and communication. -// -// Values containing the types defined in this package should not be copied. -package sync - -import ( - "sync/atomic" - "unsafe" -) - -// A Mutex is a mutual exclusion lock. -// Mutexes can be created as part of other structures; -// the zero value for a Mutex is an unlocked mutex. -type Mutex struct { - state int32 - sema uint32 -} - -// A Locker represents an object that can be locked and unlocked. -type Locker interface { - Lock() - Unlock() -} - -const ( - mutexLocked = 1 << iota // mutex is locked - mutexWoken - mutexWaiterShift = iota -) - -// Lock locks m. -// If the lock is already in use, the calling goroutine -// blocks until the mutex is available. -func (m *Mutex) Lock() { - // Fast path: grab unlocked mutex. - if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) { - if raceenabled { - raceAcquire(unsafe.Pointer(m)) - } - return - } - - awoke := false - for { - old := m.state - new := old | mutexLocked - if old&mutexLocked != 0 { - new = old + 1<<mutexWaiterShift - } - if awoke { - // The goroutine has been woken from sleep, - // so we need to reset the flag in either case. - new &^= mutexWoken - } - if atomic.CompareAndSwapInt32(&m.state, old, new) { - if old&mutexLocked == 0 { - break - } - runtime_Semacquire(&m.sema) - awoke = true - } - } - - if raceenabled { - raceAcquire(unsafe.Pointer(m)) - } -} - -// Unlock unlocks m. -// It is a run-time error if m is not locked on entry to Unlock. -// -// A locked Mutex is not associated with a particular goroutine. -// It is allowed for one goroutine to lock a Mutex and then -// arrange for another goroutine to unlock it. -func (m *Mutex) Unlock() { - if raceenabled { - _ = m.state - raceRelease(unsafe.Pointer(m)) - } - - // Fast path: drop lock bit. - new := atomic.AddInt32(&m.state, -mutexLocked) - if (new+mutexLocked)&mutexLocked == 0 { - panic("sync: unlock of unlocked mutex") - } - - old := new - for { - // If there are no waiters or a goroutine has already - // been woken or grabbed the lock, no need to wake anyone. - if old>>mutexWaiterShift == 0 || old&(mutexLocked|mutexWoken) != 0 { - return - } - // Grab the right to wake someone. - new = (old - 1<<mutexWaiterShift) | mutexWoken - if atomic.CompareAndSwapInt32(&m.state, old, new) { - runtime_Semrelease(&m.sema) - return - } - old = m.state - } -} |