Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "MooseTypes.h" // included for namespace usage and THREAD_ID 13 : 14 : #include "libmesh/libmesh_common.h" 15 : #include "libmesh/threads.h" 16 : 17 : #ifdef LIBMESH_HAVE_TBB_API 18 : #include "tbb/concurrent_queue.h" 19 : #include "tbb/tbb_thread.h" 20 : #elif LIBMESH_HAVE_OPENMP 21 : #include <omp.h> 22 : #elif LIBMESH_HAVE_PTHREAD 23 : #include <queue> 24 : #include "MooseException.h" 25 : #endif 26 : 27 : class ParallelUniqueId 28 : { 29 : public: 30 5648877 : ParallelUniqueId() 31 5648877 : { 32 : #ifdef LIBMESH_HAVE_TBB_API 33 : _ids.pop(id); 34 : #elif LIBMESH_HAVE_OPENMP 35 5648877 : id = omp_get_thread_num(); 36 : #elif LIBMESH_HAVE_PTHREAD 37 : Threads::spin_mutex::scoped_lock lock(_pthread_id_mutex); 38 : 39 : if (_ids.empty()) 40 : throw MooseException( 41 : "No Thread IDs available in ParallelUniqueID. Did you forget to initialize()?"); 42 : 43 : id = _ids.front(); 44 : _ids.pop(); 45 : #else 46 : // There is no thread model active, so we're always on thread 0. 47 : id = 0; 48 : #endif 49 5648877 : } 50 : 51 5648769 : ~ParallelUniqueId() 52 : { 53 : #ifdef LIBMESH_HAVE_TBB_API 54 : _ids.push(id); 55 : #elif !defined(LIBMESH_HAVE_OPENMP) && defined(LIBMESH_HAVE_PTHREAD) 56 : Threads::spin_mutex::scoped_lock lock(_pthread_id_mutex); 57 : 58 : _ids.push(id); 59 : #endif 60 5648769 : } 61 : 62 : /** 63 : * Must be called by main thread _before_ any threaded computation! 64 : * Do NOT call _in_ a worker thread! 65 : */ 66 51208 : static void initialize() 67 : { 68 51208 : if (!_initialized) 69 : { 70 51208 : _initialized = true; 71 : 72 : #if defined(LIBMESH_HAVE_TBB_API) || \ 73 : (!defined(LIBMESH_HAVE_OPENMP) && defined(LIBMESH_HAVE_PTHREAD)) 74 : for (unsigned int i = 0; i < libMesh::n_threads(); ++i) 75 : _ids.push(i); 76 : #endif 77 : } 78 51208 : } 79 : 80 : THREAD_ID id; 81 : 82 : private: 83 : #ifdef LIBMESH_HAVE_TBB_API 84 : static tbb::concurrent_bounded_queue<unsigned int> _ids; 85 : #elif !defined(LIBMESH_HAVE_OPENMP) && defined(LIBMESH_HAVE_PTHREAD) 86 : static std::queue<unsigned int> _ids; 87 : static Threads::spin_mutex _pthread_id_mutex; 88 : #endif 89 : 90 : static bool _initialized; 91 : };