aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/osutil
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2025-11-24 08:04:20 +0100
committerDmitry Vyukov <dvyukov@google.com>2025-11-24 08:55:49 +0000
commit9174555f6d933d77dace419771065710ef6df014 (patch)
treee272115ab3fa416d5105163934b5faa1f0c5fc5c /pkg/osutil
parenta6deb8053825b4c7024c2b04f5d4f5a12ace1272 (diff)
pkg/osutil: move Semaphore from pkg/instance
Semaphore is a very low-level primitive type, while pkg/instance is a very high-level package with lots of deps. Semaphore does not belong there, and may lead to cyclic deps if we use it more. Move it to pkg/osutil. It's not really OS-specific, but we don't have a better package.
Diffstat (limited to 'pkg/osutil')
-rw-r--r--pkg/osutil/semaphore.go42
1 files changed, 42 insertions, 0 deletions
diff --git a/pkg/osutil/semaphore.go b/pkg/osutil/semaphore.go
new file mode 100644
index 000000000..83d251ce0
--- /dev/null
+++ b/pkg/osutil/semaphore.go
@@ -0,0 +1,42 @@
+// Copyright 2025 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 osutil
+
+import (
+ "fmt"
+)
+
+type Semaphore struct {
+ ch chan struct{}
+}
+
+func NewSemaphore(count int) *Semaphore {
+ s := &Semaphore{
+ ch: make(chan struct{}, count),
+ }
+ for i := 0; i < count; i++ {
+ s.Signal()
+ }
+ return s
+}
+
+func (s *Semaphore) Wait() {
+ <-s.ch
+}
+
+func (s *Semaphore) WaitC() <-chan struct{} {
+ return s.ch
+}
+
+func (s *Semaphore) Available() int {
+ return len(s.ch)
+}
+
+func (s *Semaphore) Signal() {
+ if av := s.Available(); av == cap(s.ch) {
+ // Not super reliable, but let it be here just in case.
+ panic(fmt.Sprintf("semaphore capacity (%v) is exceeded (%v)", cap(s.ch), av))
+ }
+ s.ch <- struct{}{}
+}