]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add levelmu, a package implementing priority mutex with levels
authorMatt Joiner <anacrolix@gmail.com>
Sun, 24 Aug 2014 19:22:34 +0000 (05:22 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 24 Aug 2014 19:22:34 +0000 (05:22 +1000)
util/levelmu/levelmu.go [new file with mode: 0644]

diff --git a/util/levelmu/levelmu.go b/util/levelmu/levelmu.go
new file mode 100644 (file)
index 0000000..5970d72
--- /dev/null
@@ -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
+}