atomic.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. //----------------------------------------------------------------------------
  2. /// @file atomic.hpp
  3. /// @brief Basic layer for to simplify the use of atomic functions
  4. /// @author Copyright(c) 2016 Francisco José Tapia (fjtapia@gmail.com )\n
  5. /// Distributed under the Boost Software License, Version 1.0.\n
  6. /// ( See accompanying file LICENSE_1_0.txt or copy at
  7. /// http://www.boost.org/LICENSE_1_0.txt )
  8. /// @version 0.1
  9. ///
  10. /// @remarks
  11. //-----------------------------------------------------------------------------
  12. #ifndef __BOOST_SORT_PARALLEL_DETAIL_UTIL_ATOMIC_HPP
  13. #define __BOOST_SORT_PARALLEL_DETAIL_UTIL_ATOMIC_HPP
  14. #include <ciso646>
  15. #include <atomic>
  16. #include <cassert>
  17. #include <type_traits>
  18. namespace boost
  19. {
  20. namespace sort
  21. {
  22. namespace common
  23. {
  24. namespace util
  25. {
  26. //-----------------------------------------------------------------------------
  27. // function : atomic_read
  28. /// @brief make the atomic read of an atomic variable, using a memory model
  29. /// @param at_var : atomic variable to read
  30. /// @return value obtained
  31. //-----------------------------------------------------------------------------
  32. template<typename T>
  33. inline T atomic_read(std::atomic<T> &at_var)
  34. {
  35. return std::atomic_load_explicit < T > (&at_var, std::memory_order_acquire);
  36. };
  37. //
  38. //-----------------------------------------------------------------------------
  39. // function : atomic_add
  40. /// @brief Add a number to an atomic variable, using a memory model
  41. /// @param at_var : variable to add
  42. /// @param num : value to add to at_var
  43. /// @return result of the operation
  44. //-----------------------------------------------------------------------------
  45. template<typename T, typename T2>
  46. inline T atomic_add(std::atomic<T> &at_var, T2 num)
  47. {
  48. static_assert (std::is_integral< T2 >::value, "Bad parameter");
  49. return std::atomic_fetch_add_explicit <T>
  50. (&at_var, (T) num, std::memory_order_acq_rel);
  51. };
  52. //
  53. //-----------------------------------------------------------------------------
  54. // function : atomic_sub
  55. /// @brief Atomic subtract of an atomic variable using memory model
  56. /// @param at_var : Varibale to subtract
  57. /// @param num : value to sub to at_var
  58. /// @return result of the operation
  59. //-----------------------------------------------------------------------------
  60. template<typename T, typename T2>
  61. inline T atomic_sub(std::atomic<T> &at_var, T2 num)
  62. {
  63. static_assert (std::is_integral< T2 >::value, "Bad parameter");
  64. return std::atomic_fetch_sub_explicit <T>
  65. (&at_var, (T) num, std::memory_order_acq_rel);
  66. };
  67. //
  68. //-----------------------------------------------------------------------------
  69. // function : atomic_write
  70. /// @brief Write a value in an atomic variable using memory model
  71. /// @param at_var : varible to write
  72. /// @param num : value to write in at_var
  73. //-----------------------------------------------------------------------------
  74. template<typename T, typename T2>
  75. inline void atomic_write(std::atomic<T> &at_var, T2 num)
  76. {
  77. static_assert (std::is_integral< T2 >::value, "Bad parameter");
  78. std::atomic_store_explicit <T>
  79. (&at_var, (T) num, std::memory_order_release);
  80. };
  81. template<typename T>
  82. struct counter_guard
  83. {
  84. typedef std::atomic<T> atomic_t;
  85. atomic_t &count;
  86. counter_guard(atomic_t & counter): count(counter) { };
  87. ~counter_guard() {atomic_sub(count, 1); };
  88. };
  89. //
  90. //****************************************************************************
  91. };// End namespace util
  92. };// End namespace common
  93. };// End namespace sort
  94. };// End namespace boost
  95. //****************************************************************************
  96. #endif