10 #ifndef EIGEN_CXX11_THREADPOOL_THREAD_LOCAL_H
11 #define EIGEN_CXX11_THREADPOOL_THREAD_LOCAL_H
13 #ifdef EIGEN_AVOID_THREAD_LOCAL
15 #ifdef EIGEN_THREAD_LOCAL
16 #undef EIGEN_THREAD_LOCAL
21 #if ((EIGEN_COMP_GNUC) || __has_feature(cxx_thread_local) || EIGEN_COMP_MSVC )
22 #define EIGEN_THREAD_LOCAL static thread_local
26 #if defined(__APPLE__)
29 #include <Availability.h>
30 #include <TargetConditionals.h>
34 #if EIGEN_COMP_CLANGAPPLE && ((EIGEN_COMP_CLANGAPPLE < 8000042) || \
35 (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0))
38 #undef EIGEN_THREAD_LOCAL
40 #elif defined(__ANDROID__) && EIGEN_COMP_CLANG
49 #if __has_include(<android/ndk-version.h>)
50 #include <android/ndk-version.h>
52 #if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \
53 defined(__NDK_MINOR__) && \
54 ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))
55 #undef EIGEN_THREAD_LOCAL
67 struct ThreadLocalNoOpInitialize {
72 struct ThreadLocalNoOpRelease {
110 template <
typename T,
111 typename Initialize = internal::ThreadLocalNoOpInitialize<T>,
112 typename Release = internal::ThreadLocalNoOpRelease<T>>
115 static_assert(std::is_default_constructible<T>::value,
116 "ThreadLocal data type must be default constructible");
121 internal::ThreadLocalNoOpRelease<
T>()) {}
125 internal::ThreadLocalNoOpRelease<
T>()) {}
137 ptr_.emplace_back(
nullptr);
142 std::thread::id this_thread = std::this_thread::get_id();
145 std::size_t h = std::hash<std::thread::id>()(this_thread);
157 while (
ptr_[idx].load() !=
nullptr) {
163 if (idx == start_idx)
break;
176 int insertion_index =
182 data_[insertion_index].thread_id = this_thread;
195 const int insertion_idx = idx;
200 while (
ptr_[idx].load() !=
nullptr) {
209 }
while (!
ptr_[idx].compare_exchange_weak(empty, inserted));
211 return inserted->
value;
215 void ForEach(std::function<
void(std::thread::id,
T&)> f) {
218 for (
auto& ptr :
ptr_) {
220 if (record ==
nullptr)
continue;
230 f(kv.first, kv.second);
238 for (
auto& ptr :
ptr_) {
240 if (record ==
nullptr)
continue;
269 return (*result.first).second;
IndexedView_or_Block operator()(const RowIndices &rowIndices, const ColIndices &colIndices)
Eigen::Triplet< double > T
T & SpilledLocal(std::thread::id this_thread)
ThreadLocal(int capacity)
ThreadLocal(int capacity, Initialize initialize)
void ForEach(std::function< void(std::thread::id, T &)> f)
MaxSizeVector< ThreadIdAndValue > data_
MaxSizeVector< std::atomic< ThreadIdAndValue * > > ptr_
std::atomic< int > filled_records_
ThreadLocal(int capacity, Initialize initialize, Release release)
std::unordered_map< std::thread::id, T > per_thread_map_
std::thread::id thread_id