URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [sync/] [mutex.go] - Rev 867
Go to most recent revision | 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 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 syncimport ("runtime""sync/atomic")// 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 int32sema uint32}// A Locker represents an object that can be locked and unlocked.type Locker interface {Lock()Unlock()}const (mutexLocked = 1 << iota // mutex is lockedmutexWokenmutexWaiterShift = 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) {return}awoke := falsefor {old := m.statenew := old | mutexLockedif 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}}}// 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() {// Fast path: drop lock bit.new := atomic.AddInt32(&m.state, -mutexLocked)if (new+mutexLocked)&mutexLocked == 0 {panic("sync: unlock of unlocked mutex")}old := newfor {// 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) | mutexWokenif atomic.CompareAndSwapInt32(&m.state, old, new) {runtime.Semrelease(&m.sema)return}old = m.state}}
Go to most recent revision | Compare with Previous | Blame | View Log
