From 9174555f6d933d77dace419771065710ef6df014 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 24 Nov 2025 08:04:20 +0100 Subject: 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. --- pkg/osutil/semaphore.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 pkg/osutil/semaphore.go (limited to 'pkg/osutil') 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{}{} +} -- cgit mrf-deployment