atomic.hpp 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 <atomic>
  15. #include <cassert>
  16. #include <type_traits>
  17. namespace boost
  18. {
  19. namespace sort
  20. {
  21. namespace common
  22. {
  23. namespace util
  24. {
  25. //-----------------------------------------------------------------------------
  26. // function : atomic_read
  27. /// @brief make the atomic read of an atomic variable, using a memory model
  28. /// @param at_var : atomic variable to read
  29. /// @return value obtained
  30. //-----------------------------------------------------------------------------
  31. template<typename T>
  32. inline T atomic_read(std::atomic<T> &at_var)
  33. {
  34. return std::atomic_load_explicit < T > (&at_var, std::memory_order_acquire);
  35. };
  36. //
  37. //-----------------------------------------------------------------------------
  38. // function : atomic_add
  39. /// @brief Add a number to an atomic variable, using a memory model
  40. /// @param at_var : variable to add
  41. /// @param num : value to add to at_var
  42. /// @return result of the operation
  43. //-----------------------------------------------------------------------------
  44. template<typename T, typename T2>
  45. inline T atomic_add(std::atomic<T> &at_var, T2 num)
  46. {
  47. static_assert (std::is_integral< T2 >::value, "Bad parameter");
  48. return std::atomic_fetch_add_explicit <T>
  49. (&at_var, (T) num, std::memory_order_acq_rel);
  50. };
  51. //
  52. //-----------------------------------------------------------------------------
  53. // function : atomic_sub
  54. /// @brief Atomic subtract of an atomic variable using memory model
  55. /// @param at_var : Varibale to subtract
  56. /// @param num : value to sub to at_var
  57. /// @return result of the operation
  58. //-----------------------------------------------------------------------------
  59. template<typename T, typename T2>
  60. inline T atomic_sub(std::atomic<T> &at_var, T2 num)
  61. {
  62. static_assert (std::is_integral< T2 >::value, "Bad parameter");
  63. return std::atomic_fetch_sub_explicit <T>
  64. (&at_var, (T) num, std::memory_order_acq_rel);
  65. };
  66. //
  67. //-----------------------------------------------------------------------------
  68. // function : atomic_write
  69. /// @brief Write a value in an atomic variable using memory model
  70. /// @param at_var : varible to write
  71. /// @param num : value to write in at_var
  72. //-----------------------------------------------------------------------------
  73. template<typename T, typename T2>
  74. inline void atomic_write(std::atomic<T> &at_var, T2 num)
  75. {
  76. static_assert (std::is_integral< T2 >::value, "Bad parameter");
  77. std::atomic_store_explicit <T>
  78. (&at_var, (T) num, std::memory_order_release);
  79. };
  80. template<typename T>
  81. struct counter_guard
  82. {
  83. typedef std::atomic<T> atomic_t;
  84. atomic_t &count;
  85. counter_guard(atomic_t & counter): count(counter) { };
  86. ~counter_guard() {atomic_sub(count, 1); };
  87. };
  88. //
  89. //****************************************************************************
  90. };// End namespace util
  91. };// End namespace common
  92. };// End namespace sort
  93. };// End namespace boost
  94. //****************************************************************************
  95. #endif