AtomicCounter.hpp 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  4. *
  5. * (c) ZeroTier, Inc.
  6. * https://www.zerotier.com/
  7. */
  8. #ifndef ZT_ATOMICCOUNTER_HPP
  9. #define ZT_ATOMICCOUNTER_HPP
  10. #ifndef __GNUC__
  11. #include <atomic>
  12. #endif
  13. namespace ZeroTier {
  14. /**
  15. * Simple atomic counter supporting increment and decrement
  16. */
  17. class AtomicCounter {
  18. public:
  19. AtomicCounter()
  20. {
  21. _v = 0;
  22. }
  23. inline int load() const
  24. {
  25. #ifdef __GNUC__
  26. return __sync_or_and_fetch(const_cast<int*>(&_v), 0);
  27. #else
  28. return _v.load();
  29. #endif
  30. }
  31. inline int operator++()
  32. {
  33. #ifdef __GNUC__
  34. return __sync_add_and_fetch(&_v, 1);
  35. #else
  36. return ++_v;
  37. #endif
  38. }
  39. inline int operator--()
  40. {
  41. #ifdef __GNUC__
  42. return __sync_sub_and_fetch(&_v, 1);
  43. #else
  44. return --_v;
  45. #endif
  46. }
  47. private:
  48. AtomicCounter(const AtomicCounter&)
  49. {
  50. }
  51. const AtomicCounter& operator=(const AtomicCounter&)
  52. {
  53. return *this;
  54. }
  55. #ifdef __GNUC__
  56. int _v;
  57. #else
  58. std::atomic_int _v;
  59. #endif
  60. };
  61. } // namespace ZeroTier
  62. #endif