Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/ptl/include/PTL/UserTaskQueue.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // MIT License
  3 // Copyright (c) 2020 Jonathan R. Madsen
  4 // Permission is hereby granted, free of charge, to any person obtaining a copy
  5 // of this software and associated documentation files (the "Software"), to deal
  6 // in the Software without restriction, including without limitation the rights
  7 // to use, copy, modify, merge, publish, distribute, sublicense, and
  8 // copies of the Software, and to permit persons to whom the Software is
  9 // furnished to do so, subject to the following conditions:
 10 // The above copyright notice and this permission notice shall be included in
 11 // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 18 //
 19 //  ---------------------------------------------------------------
 20 //  Tasking class header
 21 //  Class Description:
 22 //  ---------------------------------------------------------------
 23 //  Author: Jonathan Madsen
 24 //  ---------------------------------------------------------------
 25 
 26 #pragma once
 27 
 28 #include "PTL/Macros.hh"
 29 #include "PTL/TaskSubQueue.hh"
 30 #include "PTL/Types.hh"
 31 #include "PTL/VUserTaskQueue.hh"
 32 
 33 #include <atomic>
 34 #include <cstdint>
 35 #include <memory>
 36 #include <random>
 37 #include <vector>
 38 
 39 namespace PTL
 40 {
 41 class ThreadData;
 42 class ThreadPool;
 43 class VTask;
 44 
 45 class UserTaskQueue : public VUserTaskQueue
 46 {
 47 public:
 48     using task_pointer          = std::shared_ptr<VTask>;
 49     using TaskSubQueueContainer = std::vector<TaskSubQueue*>;
 50     using random_engine_t       = std::default_random_engine;
 51     using int_dist_t            = std::uniform_int_distribution<int>;
 52 
 53 public:
 54     // Constructor and Destructors
 55     UserTaskQueue(intmax_t nworkers = -1, UserTaskQueue* = nullptr);
 56     // Virtual destructors are required by abstract classes
 57     // so add it by default, just in case
 58     ~UserTaskQueue() override;
 59 
 60 public:
 61     // Virtual  function for getting a task from the queue
 62     task_pointer GetTask(intmax_t subq = -1, intmax_t nitr = -1) override;
 63     // Virtual function for inserting a task into the queue
 64     intmax_t InsertTask(task_pointer&&, ThreadData* = nullptr,
 65                         intmax_t subq = -1) override PTL_NO_SANITIZE_THREAD;
 66 
 67     // if executing only tasks in threads bin
 68     task_pointer GetThreadBinTask();
 69 
 70     // Overload this function to hold threads
 71     void Wait() override {}
 72     void resize(intmax_t) override;
 73 
 74     bool      empty() const override;
 75     size_type size() const override;
 76 
 77     size_type bin_size(size_type bin) const override;
 78     bool      bin_empty(size_type bin) const override;
 79 
 80     bool      true_empty() const override;
 81     size_type true_size() const override;
 82 
 83     void ExecuteOnAllThreads(ThreadPool* tp, function_type f) override;
 84 
 85     void ExecuteOnSpecificThreads(ThreadIdSet tid_set, ThreadPool* tp,
 86                                   function_type f) override;
 87 
 88     VUserTaskQueue* clone() override;
 89 
 90     intmax_t GetThreadBin() const override;
 91 
 92 protected:
 93     intmax_t GetInsertBin() const;
 94 
 95 private:
 96     void AcquireHold();
 97     void ReleaseHold();
 98 
 99 private:
100     bool                       m_is_clone;
101     intmax_t                   m_thread_bin;
102     mutable intmax_t           m_insert_bin;
103     std::atomic_bool*          m_hold      = nullptr;
104     std::atomic_uintmax_t*     m_ntasks    = nullptr;
105     Mutex*                     m_mutex     = nullptr;
106     TaskSubQueueContainer*     m_subqueues = nullptr;
107     std::vector<int>           m_rand_list = {};
108     std::vector<int>::iterator m_rand_itr  = {};
109 };
110 
111 //======================================================================================//
112 
113 inline bool
114 UserTaskQueue::empty() const
115 {
116     return (m_ntasks->load(std::memory_order_relaxed) == 0);
117 }
118 
119 //======================================================================================//
120 
121 inline UserTaskQueue::size_type
122 UserTaskQueue::size() const
123 {
124     return m_ntasks->load(std::memory_order_relaxed);
125 }
126 
127 //======================================================================================//
128 
129 inline UserTaskQueue::size_type
130 UserTaskQueue::bin_size(size_type bin) const
131 {
132     return (*m_subqueues)[bin]->size();
133 }
134 
135 //======================================================================================//
136 
137 inline bool
138 UserTaskQueue::bin_empty(size_type bin) const
139 {
140     return (*m_subqueues)[bin]->empty();
141 }
142 
143 //======================================================================================//
144 
145 inline bool
146 UserTaskQueue::true_empty() const
147 {
148     for(const auto& itr : *m_subqueues)
149         if(!itr->empty())
150             return false;
151     return true;
152 }
153 
154 //======================================================================================//
155 
156 inline UserTaskQueue::size_type
157 UserTaskQueue::true_size() const
158 {
159     size_type _n = 0;
160     for(const auto& itr : *m_subqueues)
161         _n += itr->size();
162     return _n;
163 }
164 
165 //======================================================================================//
166 }  // namespace PTL
167