diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2015-12-16 17:10:52 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2015-12-17 14:38:46 +0100 |
| commit | d665e11e9df6cd99160817aad775bacdbbd2e26f (patch) | |
| tree | 0d9092bced32d534e4023de269d7a281d0990abc /ipc | |
| parent | ce0bb4c05d45db0bba56c5ab11d2b1d7c17e002a (diff) | |
move Gate type to ipc package and use it in stress tool
This allows to print what programs stress executes.
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/gate.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/ipc/gate.go b/ipc/gate.go new file mode 100644 index 000000000..941dc9f2a --- /dev/null +++ b/ipc/gate.go @@ -0,0 +1,54 @@ +// Copyright 2015 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package ipc + +import ( + "sync" +) + +// Gate limits concurrency level and window to the given value. +// Limitation of concurrency window means that if a very old activity is still +// running it will not let new activities to start even if concurrency level is low. +type Gate struct { + cv *sync.Cond + busy []bool + pos int +} + +func NewGate(c int) *Gate { + return &Gate{ + cv: sync.NewCond(new(sync.Mutex)), + busy: make([]bool, c), + } +} + +func (g *Gate) Enter() int { + g.cv.L.Lock() + for g.busy[g.pos] { + g.cv.Wait() + } + idx := g.pos + g.pos++ + if g.pos >= len(g.busy) { + g.pos = 0 + } + g.busy[idx] = true + g.cv.L.Unlock() + return idx +} + +func (g *Gate) Leave(idx int, f func()) { + g.cv.L.Lock() + if !g.busy[idx] { + panic("broken gate") + } + if f != nil { + f() + } + g.busy[idx] = false + if idx == g.pos { + g.cv.Broadcast() + } + g.cv.L.Unlock() +} |
