From caa1d65bc8b43dbd8ac34bc4d34f5af1e42daa7f Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 25 Aug 2014 05:22:34 +1000 Subject: [PATCH] Add levelmu, a package implementing priority mutex with levels --- util/levelmu/levelmu.go | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 util/levelmu/levelmu.go diff --git a/util/levelmu/levelmu.go b/util/levelmu/levelmu.go new file mode 100644 index 00000000..5970d721 --- /dev/null +++ b/util/levelmu/levelmu.go @@ -0,0 +1,39 @@ +package levelmu + +import ( + "sync" +) + +type LevelMutex struct { + mus []sync.Mutex + // Protected by the very last mutex. + lastLevel int +} + +func (lm *LevelMutex) Init(levels int) { + if lm.mus != nil { + panic("level mutex already initialized") + } + lm.mus = make([]sync.Mutex, levels) +} + +func (lm *LevelMutex) Lock() { + lm.LevelLock(0) +} + +func (lm *LevelMutex) Unlock() { + stopLevel := lm.lastLevel + for i := len(lm.mus) - 1; i >= stopLevel; i-- { + lm.mus[i].Unlock() + } +} + +func (lm *LevelMutex) LevelLock(level int) { + if level >= len(lm.mus) { + panic("lock level exceeds configured level count") + } + for l := level; l < len(lm.mus); l++ { + lm.mus[l].Lock() + } + lm.lastLevel = level +} -- 2.48.1