diff --git a/src/core/impl/utils/thread.cpp b/src/core/impl/utils/thread.cpp index 5e5b249cf74e80e86a7c678e8ac413a203b77a6c..02fe6f1bb59ec54ede76fcb358335ce02fe04fc9 100644 --- a/src/core/impl/utils/thread.cpp +++ b/src/core/impl/utils/thread.cpp @@ -257,6 +257,20 @@ void SyncableCounter::wait_zero() { } } +/* =============== ThreadLocalForceFree =============== */ +#if defined(__ANDROID__) && !USE_STL_THREAD_LOCAL +void ThreadLocalForceFree::push(void* d) { + MGB_LOCK_GUARD(m_mutex); + td.push_back(d); +} + +//! make ff init as soon as possible +static ThreadLocalForceFree ff; +ThreadLocalForceFree& get_thread_local_force_free_instance() { + return ff; +} +#endif + #else // MGB_HAVE_THREAD #pragma message "threading support is disabled" #if MGB_CUDA diff --git a/src/core/include/megbrain/utils/thread_local.h b/src/core/include/megbrain/utils/thread_local.h index 3b968e02b35e5cc3746480585747a2043cd3b0a2..b453850cfd0f8d8d78d84ada776b5afdb69e3386 100644 --- a/src/core/include/megbrain/utils/thread_local.h +++ b/src/core/include/megbrain/utils/thread_local.h @@ -22,6 +22,24 @@ #pragma message("force disable USE_STL_THREAD_LOCAL for thread_local mem leak at dlopen/dlclose") #undef USE_STL_THREAD_LOCAL #define USE_STL_THREAD_LOCAL 0 +class ThreadData; +class ThreadLocalForceFree { +public: + ThreadLocalForceFree() = default; + ~ThreadLocalForceFree() { + MGB_LOCK_GUARD(m_mutex); + for (auto& d : td) { + delete (ThreadData*)d; + } + } + + void push(void* d); + +private: + std::vector td; + MGB_MUTEX m_mutex; +}; +ThreadLocalForceFree& get_thread_local_force_free_instance(); #endif #if USE_STL_THREAD_LOCAL @@ -57,6 +75,10 @@ class ThreadLocalPtr { return static_cast(d)->data; } ThreadData* t_data = new ThreadData(); +#if defined(__ANDROID__) + get_thread_local_force_free_instance().push((void*)t_data); +#endif + t_data->data = m_constructor(); t_data->self = this; pthread_setspecific(m_key, t_data); @@ -67,7 +89,9 @@ class ThreadLocalPtr { ThreadData* td = static_cast(d); if (td && td->self->m_destructor) td->self->m_destructor(td->data); +#if !defined(__ANDROID__) delete td; +#endif } public: