feat-debug(thread_pool): log the job and which thread execute it for debugging purposes in case the thread never exit. also log in case a job is scheduled but none of the thread are currently available (#1190)

This commit is contained in:
Quentin E. / iDeath 2023-04-04 23:52:57 +02:00 committed by GitHub
parent e1ce85fd71
commit 626394eca7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 8 deletions

View File

@ -22,6 +22,8 @@ namespace big
LOG(VERBOSE) << "Allocating " << thread_count << " threads in thread pool.";
this->m_thread_pool.reserve(thread_count);
m_available_thread_count = thread_count;
for (std::uint32_t i = 0; i < thread_count; i++)
this->m_thread_pool.emplace_back(std::thread(&thread_pool::run, this));
}
@ -41,13 +43,18 @@ namespace big
m_thread_pool.clear();
}
void thread_pool::push(std::function<void()> func)
void thread_pool::push(std::function<void()> func, std::source_location location)
{
if (func)
{
{
std::unique_lock lock(this->m_lock);
this->m_job_stack.push(std::move(func));
this->m_job_stack.push({func, location});
if (m_available_thread_count < m_job_stack.size())
{
LOG(WARNING) << "thread_pool potentially starved";
}
}
this->m_data_condition.notify_all();
}
@ -68,18 +75,26 @@ namespace big
if (this->m_job_stack.empty())
continue;
std::function<void()> job = std::move(this->m_job_stack.top());
thread_pool_job job = this->m_job_stack.top();
this->m_job_stack.pop();
lock.unlock();
m_available_thread_count--;
try
{
std::invoke(std::move(job));
const auto source_file = std::filesystem::path(job.m_source_location.file_name()).filename().string();
LOG(VERBOSE) << "Thread " << std::this_thread::get_id() << " executing " << source_file << ":"
<< job.m_source_location.line();
std::invoke(job.m_func);
}
catch (const std::exception& e)
{
LOG(WARNING) << "Exception thrown while executing job in thread:" << std::endl << e.what();
}
m_available_thread_count++;
}
LOG(VERBOSE) << "Thread " << std::this_thread::get_id() << " exiting...";

View File

@ -2,23 +2,31 @@
namespace big
{
struct thread_pool_job
{
std::function<void()> m_func;
std::source_location m_source_location;
};
class thread_pool
{
std::atomic<bool> m_accept_jobs;
std::condition_variable m_data_condition;
std::stack<std::function<void()>> m_job_stack;
std::stack<thread_pool_job> m_job_stack;
std::mutex m_lock;
std::vector<std::thread> m_thread_pool;
std::thread m_managing_thread;
std::atomic<size_t> m_available_thread_count;
public:
thread_pool();
~thread_pool();
void destroy();
void push(std::function<void()> func);
void push(std::function<void()> func, std::source_location location = std::source_location::current());
private:
void create();