1 // Copyright (C) 2016 John Biddiscombe 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 6 #ifndef HPT_PARCELSET_POLICIES_VERBS_PERFORMANCE_COUNTER_HPP 7 #define HPT_PARCELSET_POLICIES_VERBS_PERFORMANCE_COUNTER_HPP 8 9 #include <hpx/config/parcelport_defines.hpp> 10 #include <plugins/parcelport/parcelport_logging.hpp> 11 // 12 #include <atomic> 13 #include <type_traits> 14 #include <iostream> 15 16 #ifdef HPX_PARCELPORT_LIBFABRIC_HAVE_PERFORMANCE_COUNTERS 17 # define PERFORMANCE_COUNTER_ENABLED true 18 #else 19 # define PERFORMANCE_COUNTER_ENABLED false 20 #endif 21 22 // 23 // This class is intended to provide a simple atomic counter that can be used as a 24 // performance counter, but that can be disabled at compile time so that it 25 // has no performance cost when not used. It is only to avoid a lot of #ifdef 26 // statements in user code that we collect everything in here and then provide 27 // the performance counter that will simply do nothing when disabled - but 28 // still allow code that uses the counters in arithmetic to compile. 29 // 30 namespace hpx { 31 namespace parcelset 32 { 33 template <bool B, typename T = void> 34 using enable_if_t = typename std::enable_if<B, T>::type; 35 36 template <typename T, 37 bool enabled=PERFORMANCE_COUNTER_ENABLED, 38 typename Enable = enable_if_t<std::is_integral<T>::value> 39 > 40 struct performance_counter {}; 41 42 // -------------------------------------------------------------------- 43 // specialization for performance counters Enabled 44 // we provide an atomic<T> that can be incremented or added/subtracted to 45 template <typename T> 46 struct performance_counter<T, true> 47 { performance_counterhpx::parcelset::performance_counter48 performance_counter() : value_{T()} {} 49 performance_counterhpx::parcelset::performance_counter50 performance_counter(const T& init) : value_{init} {} 51 operator Thpx::parcelset::performance_counter52 inline operator T() const { return value_; } 53 operator =hpx::parcelset::performance_counter54 inline T operator=(const T& x) { return value_ = x; } 55 operator ++hpx::parcelset::performance_counter56 inline T operator++() { return ++value_; } 57 operator ++hpx::parcelset::performance_counter58 inline T operator++(int x) { return (value_ += x); } 59 operator +=hpx::parcelset::performance_counter60 inline T operator+=(const T& rhs) { return (value_ += rhs); } 61 operator --hpx::parcelset::performance_counter62 inline T operator--() { return --value_; } 63 operator --hpx::parcelset::performance_counter64 inline T operator--(int x) { return (value_ -= x); } 65 operator -=hpx::parcelset::performance_counter66 inline T operator-=(const T& rhs) { return (value_ -= rhs); } 67 operator <<(std::ostream & os,const performance_counter<T,true> & x)68 friend std::ostream& operator<<(std::ostream& os, 69 const performance_counter<T, true>& x) 70 { 71 os << x.value_; 72 return os; 73 } 74 75 std::atomic<T> value_; 76 }; 77 78 // -------------------------------------------------------------------- 79 // specialization for performance counters Disabled 80 // just return dummy values so that arithmetic operations compile ok 81 template <typename T> 82 struct performance_counter<T, false> 83 { performance_counterhpx::parcelset::performance_counter84 performance_counter() {} 85 performance_counterhpx::parcelset::performance_counter86 performance_counter(const T&) {} 87 operator Thpx::parcelset::performance_counter88 inline operator T() const { return 0; } 89 operator =hpx::parcelset::performance_counter90 inline T operator=(const T&) { return 0; } 91 operator ++hpx::parcelset::performance_counter92 inline T operator++() { return 0; } 93 operator ++hpx::parcelset::performance_counter94 inline T operator++(int) { return 0; } 95 operator +=hpx::parcelset::performance_counter96 inline T operator+=(const T&) { return 0; } 97 operator --hpx::parcelset::performance_counter98 inline T operator--() { return 0; } 99 operator --hpx::parcelset::performance_counter100 inline T operator--(int) { return 0; } 101 operator -=hpx::parcelset::performance_counter102 inline T operator-=(const T&) { return 0; } 103 operator <<(std::ostream & os,const performance_counter<T,false> & x)104 friend std::ostream& operator<<(std::ostream& os, 105 const performance_counter<T, false>& x) 106 { 107 os << "undefined"; 108 return os; 109 } 110 }; 111 }} 112 113 #endif 114 115