1 /* 2 * per_thread_bool_indicator.h 3 * 4 * This file is part of NEST. 5 * 6 * Copyright (C) 2004 The NEST Initiative 7 * 8 * NEST is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * NEST is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with NEST. If not, see <http://www.gnu.org/licenses/>. 20 * 21 */ 22 23 #ifndef PER_THREAD_BOOL_INDICATOR_H 24 #define PER_THREAD_BOOL_INDICATOR_H 25 26 // C++ includes: 27 #include <cassert> 28 #include <cstddef> 29 #include <cstdint> 30 31 // Includes from nestkernel: 32 #include "nest_types.h" 33 #include "vp_manager.h" 34 35 // Includes from sli: 36 #include "dictdatum.h" 37 38 namespace nest 39 { 40 41 /** 42 * A wrapper class for an integer that is only allowed to take the 43 * values 0 and 1. Used by PerThreadBoolIndicator to create a 44 * thread-safe vector indicating per-thread status. See issue #1394. 45 */ 46 class BoolIndicatorUInt64 47 { 48 public: 49 BoolIndicatorUInt64(); 50 BoolIndicatorUInt64( const bool status ); 51 52 bool is_true() const; 53 bool is_false() const; 54 55 void set_true(); 56 void set_false(); 57 58 void logical_and( const bool status ); 59 60 private: 61 static constexpr std::uint_fast64_t true_uint64 = true; 62 static constexpr std::uint_fast64_t false_uint64 = false; 63 std::uint_fast64_t status_; 64 }; 65 66 inline bool is_true()67BoolIndicatorUInt64::is_true() const 68 { 69 return ( status_ == true_uint64 ); 70 } 71 72 inline bool is_false()73BoolIndicatorUInt64::is_false() const 74 { 75 return ( status_ == false_uint64 ); 76 } 77 78 inline void set_true()79BoolIndicatorUInt64::set_true() 80 { 81 status_ = true_uint64; 82 } 83 84 inline void set_false()85BoolIndicatorUInt64::set_false() 86 { 87 status_ = false_uint64; 88 } 89 90 inline void logical_and(const bool status)91BoolIndicatorUInt64::logical_and( const bool status ) 92 { 93 status_ = ( static_cast< bool >( status_ ) and status ); 94 } 95 96 /** 97 * A thread-safe vector to keep track of the status across threads, 98 * for example during gather operations. Uses a vector of integers 99 * instead of a vector of bools to guarantee thread safety. 100 * See issue #1394. 101 */ 102 class PerThreadBoolIndicator 103 { 104 public: PerThreadBoolIndicator()105 PerThreadBoolIndicator(){}; 106 107 BoolIndicatorUInt64& operator[]( const thread tid ); 108 109 /** 110 * Resize to the given number of threads and set all elements to false. 111 */ 112 void initialize( const thread num_threads, const bool status ); 113 114 /** 115 * Waits for all threads and returns whether all elements are false. 116 */ 117 bool all_false() const; 118 119 /** 120 * Waits for all threads and returns whether all elements are true. 121 */ 122 bool all_true() const; 123 124 /** 125 * Waits for all threads and returns whether any elements are false. 126 */ 127 bool any_false() const; 128 129 /** 130 * Waits for all threads and returns whether any elements are true. 131 */ 132 bool any_true() const; 133 134 private: 135 std::vector< BoolIndicatorUInt64 > per_thread_status_; 136 }; 137 138 } // namespace nest 139 140 #endif /* PER_THREAD_BOOL_INDICATOR_H */ 141