counter.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package context
  2. import (
  3. "math"
  4. "sync/atomic"
  5. )
  6. // Counter is the shared counter instances between Iris applications of the same process.
  7. var Counter = NewGlobalCounter() // it's not used anywhere, currently but it's here.
  8. // NewGlobalCounter returns a fresh instance of a global counter.
  9. // End developers can use it as a helper for their applications.
  10. func NewGlobalCounter() *GlobalCounter {
  11. return &GlobalCounter{Max: math.MaxUint64}
  12. }
  13. // GlobalCounter is a counter which
  14. // atomically increments until Max.
  15. type GlobalCounter struct {
  16. value uint64
  17. Max uint64
  18. }
  19. // Increment increments the Value.
  20. // The value cannot exceed the Max one.
  21. // It uses Compare and Swap with the atomic package.
  22. //
  23. // Returns the new number value.
  24. func (c *GlobalCounter) Increment() (newValue uint64) {
  25. for {
  26. prev := atomic.LoadUint64(&c.value)
  27. newValue = prev + 1
  28. if newValue >= c.Max {
  29. newValue = 0
  30. }
  31. if atomic.CompareAndSwapUint64(&c.value, prev, newValue) {
  32. break
  33. }
  34. }
  35. return
  36. }
  37. // Get returns the current counter without incrementing.
  38. func (c *GlobalCounter) Get() uint64 {
  39. return atomic.LoadUint64(&c.value)
  40. }