github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/osutil/semaphore.go (about)

     1  // Copyright 2025 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package osutil
     5  
     6  import (
     7  	"fmt"
     8  )
     9  
    10  type Semaphore struct {
    11  	ch chan struct{}
    12  }
    13  
    14  func NewSemaphore(count int) *Semaphore {
    15  	s := &Semaphore{
    16  		ch: make(chan struct{}, count),
    17  	}
    18  	for i := 0; i < count; i++ {
    19  		s.Signal()
    20  	}
    21  	return s
    22  }
    23  
    24  func (s *Semaphore) Wait() {
    25  	<-s.ch
    26  }
    27  
    28  func (s *Semaphore) WaitC() <-chan struct{} {
    29  	return s.ch
    30  }
    31  
    32  func (s *Semaphore) Available() int {
    33  	return len(s.ch)
    34  }
    35  
    36  func (s *Semaphore) Signal() {
    37  	if av := s.Available(); av == cap(s.ch) {
    38  		// Not super reliable, but let it be here just in case.
    39  		panic(fmt.Sprintf("semaphore capacity (%v) is exceeded (%v)", cap(s.ch), av))
    40  	}
    41  	s.ch <- struct{}{}
    42  }