Eigen::ThreadPool::CurrentThreadId returns wrong thread id when compile with EIGEN_AVOID_THREAD_LOCAL && NDEBUG
Windows XP have a broken TLS implementation, so i need define macro EIGEN_AVOID_THREAD_LOCAL.
in Eigen::ThreadPoolTempl::WorkerLoop(...), per_thread_map_.emplace(...) call was placed in eigen_plain_assert macro, so it will disappear in release build.
// Main worker thread loop.
void WorkerLoop(int thread_id) {
#ifndef EIGEN_THREAD_LOCAL
std::unique_ptr<PerThread> new_pt(new PerThread());
per_thread_map_mutex_.lock();
eigen_plain_assert(per_thread_map_.emplace(GlobalThreadIdHash(), std::move(new_pt)).second);
per_thread_map_mutex_.unlock();
init_barrier_->Notify();
init_barrier_->Wait();
#endif
PerThread* pt = GetPerThread();
pt->pool = this;
pt->rand = GlobalThreadIdHash();
pt->thread_id = thread_id;
...
}
then GetPerThread() will always return the same dummy PerThread, and CurrentThreadId() will return incorrect value.
EIGEN_STRONG_INLINE PerThread* GetPerThread() {
#ifndef EIGEN_THREAD_LOCAL
static PerThread dummy;
auto it = per_thread_map_.find(GlobalThreadIdHash());
if (it == per_thread_map_.end()) {
return &dummy;
} else {
return it->second.get();
}
#else
EIGEN_THREAD_LOCAL PerThread per_thread_;
PerThread* pt = &per_thread_;
return pt;
#endif
}
int CurrentThreadId() const EIGEN_FINAL {
const PerThread* pt = const_cast<ThreadPoolTempl*>(this)->GetPerThread();
if (pt->pool == this) {
return pt->thread_id;
} else {
return -1;
}
}
in TensorFlow 2.0, TFLite's conv kernel using Eigen::ThreadPool. when compile with EIGEN_AVOID_THREAD_LOCAL && NDEBUG, there are chances that inference will blocked forever.