You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

semaphores.go 1.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // Copyright (c) 2018 Shivaram Lingamneni
  2. package utils
  3. import (
  4. "log"
  5. "runtime/debug"
  6. )
  7. // Semaphore is a counting semaphore. Note that a capacity of n requires O(n) storage.
  8. // A semaphore of capacity 1 can be used as a trylock.
  9. type Semaphore (chan bool)
  10. // Initialize initializes a semaphore to a given capacity.
  11. func (semaphore *Semaphore) Initialize(capacity int) {
  12. *semaphore = make(chan bool, capacity)
  13. for i := 0; i < capacity; i++ {
  14. (*semaphore) <- true
  15. }
  16. }
  17. // Acquire acquires a semaphore, blocking if necessary.
  18. func (semaphore *Semaphore) Acquire() {
  19. <-(*semaphore)
  20. }
  21. // TryAcquire tries to acquire a semaphore, returning whether the acquire was
  22. // successful. It never blocks.
  23. func (semaphore *Semaphore) TryAcquire() (acquired bool) {
  24. select {
  25. case <-(*semaphore):
  26. return true
  27. default:
  28. return false
  29. }
  30. }
  31. // Release releases a semaphore. It never blocks. (This is not a license
  32. // to program spurious releases.)
  33. func (semaphore *Semaphore) Release() {
  34. select {
  35. case (*semaphore) <- true:
  36. // good
  37. default:
  38. // spurious release
  39. log.Printf("spurious semaphore release (full to capacity %d)", cap(*semaphore))
  40. debug.PrintStack()
  41. }
  42. }