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