blob: f781ae272e9257e7fdb8c1a18e42ffd1d5bb3553 [file] [log] [blame]
// Copyright 2015 The Vanadium 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 concurrency
// mutexState is a type to represent different states of a mutex.
type mutexState uint64
// enumeration of different mutex states.
const (
mutexFree mutexState = iota
mutexLocked
)
// fakeMutex is an abstract representation of a mutex.
type fakeMutex struct {
// clock records the logical time of the last access to the mutex.
clock clock
// state records the state of the mutex.
state mutexState
}
// newFakeMutex is the fakeMutex factory.
func newFakeMutex(clock clock) *fakeMutex {
return &fakeMutex{clock: clock.clone()}
}
// free checks if the mutex is free.
func (m *fakeMutex) free() bool {
return m.state == mutexFree
}
// locked checks if the mutex is locked.
func (m *fakeMutex) locked() bool {
return m.state == mutexLocked
}
// lock models the action of locking the mutex.
func (m *fakeMutex) lock() {
if m.state != mutexFree {
panic("Locking a mutex that is already locked.")
}
m.state = mutexLocked
}
// unlock models the action of unlocking the mutex.
func (m *fakeMutex) unlock() {
if m.state != mutexLocked {
panic("Unlocking a mutex that is not locked.")
}
m.state = mutexFree
}
// rwMutexState is a type to represent different states of a mutex.
type rwMutexState uint64
// enumeration of different rwMutex states.
const (
rwMutexFree rwMutexState = iota
rwMutexShared
rwMutexExclusive
)
// fakeRWMutex is an abstract representation of a read-write mutex.
type fakeRWMutex struct {
// clock records the logical time of the last access to the
// read-write mutex.
clock clock
// state records the state of the read-write mutex.
state rwMutexState
// nreaders records the number of readers.
nreaders int
}
// newFakeRWMutex is the fakeRWMutex factory.
func newFakeRWMutex(clock clock) *fakeRWMutex {
return &fakeRWMutex{clock: clock.clone()}
}
// exclusive checks if the read-write mutex is exclusive.
func (rw *fakeRWMutex) exclusive() bool {
return rw.state == rwMutexExclusive
}
// free checks if the read-write mutex is free.
func (rw *fakeRWMutex) free() bool {
return rw.state == rwMutexFree
}
// shared checks if the read-write mutex is shared.
func (rw *fakeRWMutex) shared() bool {
return rw.state == rwMutexShared
}
// lock models the action of read-locking or write-locking the
// read-write mutex.
func (rw *fakeRWMutex) lock(read bool) {
if read {
if rw.state == rwMutexExclusive {
panic("Read-locking a read-write mutex that is write-locked.")
}
if rw.state == rwMutexFree {
rw.state = rwMutexShared
}
rw.nreaders++
} else {
if rw.state != rwMutexFree {
panic("Write-locking a read-write mutex that is not free.")
}
rw.state = rwMutexExclusive
}
}
// unlock models the action of unlocking the read-write mutex.
func (rw *fakeRWMutex) unlock(read bool) {
if read {
if rw.state != rwMutexShared {
panic("Read-unlocking a read-write mutex that is not read-locked.")
}
rw.nreaders--
if rw.nreaders == 0 {
rw.state = rwMutexFree
}
} else {
if rw.state != rwMutexExclusive {
panic("Write-unlocking a read-write mutex that is not write-locked.")
}
rw.state = rwMutexFree
}
}