SWDEV-489158: Fix for exit thread safety (#61)

* SWDEV-489158: Fix for exit thread safety

* Fixed exit thread logic

* Force CI to rerun

* Remove .vscode

* Fix thread safety bug

* Addressed some comments

* Formatting

---------

Co-authored-by: Giovanni Baraldi <gbaraldi@amd.com>

[ROCm/rocprofiler-sdk commit: f4984f9dcc]
This commit is contained in:
Baraldi, Giovanni
2024-12-11 19:41:19 +01:00
committed by GitHub
parent 0157d4e7ff
commit 661b608227
4 changed files with 64 additions and 28 deletions
@@ -43,6 +43,8 @@
#include <cstring>
#include <ctime>
#include <fstream>
#include <limits>
#include <locale>
#include <regex>
#include <set>
#include <sstream>
@@ -66,6 +68,17 @@ const auto env_regexes =
// - %q{USER} Compatibility with NVIDIA
//
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77704
// NOLINTBEGIN
[[maybe_unused]] volatile bool _initLocale = []() {
const std::ctype<char>& ct(std::use_facet<std::ctype<char>>(std::locale()));
for(size_t i = 0; i <= std::numeric_limits<unsigned char>::max(); i++)
ct.narrow(static_cast<char>(i), '\0');
ct.narrow(0, 0, 0, 0);
return true;
}();
// NOLINTEND
std::string
format_path_impl(std::string _fpath, const std::vector<output_key>& _keys)
{
@@ -44,21 +44,23 @@ public:
void start()
{
{
std::unique_lock<std::mutex> lk(mut);
if(valid.exchange(true)) return;
}
std::unique_lock<std::mutex> lk(mut);
if(valid.exchange(true)) return;
exited.store(false);
consumer = std::thread{&consumer_thread_t::consumer_loop, this};
}
void exit()
{
{
std::unique_lock<std::mutex> lk(mut);
if(!valid.exchange(false)) return;
cv.notify_one();
}
consumer.join();
std::unique_lock<std::mutex> lk(mut);
valid.store(false);
cv.notify_all();
if(!exited) cv.wait(lk, [&] { return exited.load(); });
if(consumer.joinable()) consumer.join();
}
void add(DataType&& params)
@@ -74,7 +76,7 @@ public:
buffer.at(write_ptr % buffer.size()) = std::move(params);
write_ptr.fetch_add(1);
cv.notify_one();
cv.notify_all();
}
protected:
@@ -86,7 +88,12 @@ protected:
{
std::unique_lock<std::mutex> lk(mut);
cv.wait(lk, [&] { return read_ptr != write_ptr || !valid; });
if(!valid && read_ptr == write_ptr) return;
if(!valid && read_ptr == write_ptr)
{
exited.store(true);
cv.notify_all();
return;
}
}
auto retrieved = std::move(buffer.at(read_ptr % buffer.size()));
@@ -97,6 +104,7 @@ protected:
consume_func_t consume_fn;
std::atomic<bool> valid{false};
std::atomic<bool> exited{true};
std::mutex mut;
std::atomic<size_t> write_ptr{0};
std::atomic<size_t> read_ptr{0};