1 #ifndef SimTK_SimTKCOMMON_PARALLEL_EXECUTOR_IMPL_H_ 2 #define SimTK_SimTKCOMMON_PARALLEL_EXECUTOR_IMPL_H_ 3 4 /* -------------------------------------------------------------------------- * 5 * Simbody(tm): SimTKcommon * 6 * -------------------------------------------------------------------------- * 7 * This is part of the SimTK biosimulation toolkit originating from * 8 * Simbios, the NIH National Center for Physics-Based Simulation of * 9 * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 11 * * 12 * Portions copyright (c) 2008-12 Stanford University and the Authors. * 13 * Authors: Peter Eastman * 14 * Contributors: * 15 * * 16 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 17 * not use this file except in compliance with the License. You may obtain a * 18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 19 * * 20 * Unless required by applicable law or agreed to in writing, software * 21 * distributed under the License is distributed on an "AS IS" BASIS, * 22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 23 * See the License for the specific language governing permissions and * 24 * limitations under the License. * 25 * -------------------------------------------------------------------------- */ 26 27 #include "SimTKcommon/internal/ParallelExecutor.h" 28 #include "SimTKcommon/internal/Array.h" 29 30 #include <iostream> 31 #include <thread> 32 #include <mutex> 33 #include <condition_variable> 34 35 namespace SimTK { 36 37 class ParallelExecutorImpl; 38 39 /** 40 * This class stores per-thread information used while executing a task. 41 */ 42 43 class ThreadInfo { 44 public: ThreadInfo(int index,ParallelExecutorImpl * executor)45 ThreadInfo(int index, ParallelExecutorImpl* executor) : index(index), executor(executor), running(false) { 46 } 47 const int index; 48 ParallelExecutorImpl* const executor; 49 bool running; 50 }; 51 52 /** 53 * This is the internal implementation class for ParallelExecutor. 54 */ 55 56 class ParallelExecutorImpl : public PIMPLImplementation<ParallelExecutor, ParallelExecutorImpl> { 57 public: 58 ParallelExecutorImpl(); 59 ParallelExecutorImpl(int numThreads); 60 ~ParallelExecutorImpl(); 61 ParallelExecutorImpl* clone() const; 62 void execute(ParallelExecutor::Task& task, int times); getThreadCount()63 int getThreadCount() { 64 return threads.size(); 65 } getCurrentTask()66 ParallelExecutor::Task& getCurrentTask() { 67 return *currentTask; 68 } getCurrentTaskCount()69 int getCurrentTaskCount() { 70 return currentTaskCount; 71 } isFinished()72 bool isFinished() { 73 return finished; 74 } getMutex()75 std::mutex& getMutex() { 76 return runMutex; 77 } getCondition()78 std::condition_variable& getCondition() { 79 return runCondition; 80 } getMaxThreads()81 int getMaxThreads() const{ 82 return numMaxThreads; 83 } 84 void incrementWaitingThreads(); 85 static thread_local bool isWorker; 86 private: 87 bool finished; 88 std::mutex runMutex; 89 std::condition_variable runCondition, waitCondition; 90 Array_<std::thread> threads; 91 Array_<ThreadInfo> threadInfo; 92 ParallelExecutor::Task* currentTask; 93 int currentTaskCount; 94 int waitingThreadCount; 95 int numMaxThreads; 96 }; 97 98 } // namespace SimTK 99 100 #endif // SimTK_SimTKCOMMON_PARALLEL_EXECUTOR_IMPL_H_ 101