SWDEV-489158: Adding consumer+producer model to AST evaluation (#13)
* Rebased optizations for rocprofv3 tool * Fixing merge conflicts * Formatting * Open from within mutex * Small name changes * Added operator * removed some parameters * Optimizing counter collection * Re-arrange code * Adding back dimension query * Formatting * Update source/lib/rocprofiler-sdk/thread_trace/att_core.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Formatting 2 * Fix for test compilation * Fix for yield * Adding back check for zero * Improved thread handling * Formatting * Remove automatic start * Adding test * Small fixes * Adding lock for buffer callbacks * Fix for race condition in AST * Adding check for ptr --------- Co-authored-by: Giovanni Baraldi <gbaraldi@amd.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Cette révision appartient à :
révisé par
GitHub
Parent
c42bdc3128
révision
b7661bccfd
@@ -0,0 +1,109 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lib/rocprofiler-sdk/counters/sample_processing.hpp"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace counters
|
||||
{
|
||||
template <typename DataType>
|
||||
class consumer_thread_t
|
||||
{
|
||||
static constexpr size_t SIZE = 128;
|
||||
using consume_func_t = std::function<void(DataType&&)>;
|
||||
|
||||
public:
|
||||
consumer_thread_t(consume_func_t func) { this->consume_fn = func; }
|
||||
virtual ~consumer_thread_t() { exit(); }
|
||||
|
||||
void start()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(mut);
|
||||
if(valid.exchange(true)) return;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
void add(DataType&& params)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(mut);
|
||||
|
||||
if(read_ptr + buffer.size() <= write_ptr || !valid)
|
||||
{
|
||||
// If not possible to use consumer thread, proccess with this thread
|
||||
consume_fn(std::move(params));
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.at(write_ptr % buffer.size()) = std::move(params);
|
||||
write_ptr.fetch_add(1);
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
protected:
|
||||
void consumer_loop()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
while(read_ptr == write_ptr)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(mut);
|
||||
cv.wait(lk, [&] { return read_ptr != write_ptr || !valid; });
|
||||
if(!valid && read_ptr == write_ptr) return;
|
||||
}
|
||||
|
||||
auto retrieved = std::move(buffer.at(read_ptr % buffer.size()));
|
||||
read_ptr.fetch_add(1);
|
||||
consume_fn(std::move(retrieved));
|
||||
}
|
||||
}
|
||||
|
||||
consume_func_t consume_fn;
|
||||
std::atomic<bool> valid{false};
|
||||
std::mutex mut;
|
||||
std::atomic<size_t> write_ptr{0};
|
||||
std::atomic<size_t> read_ptr{0};
|
||||
std::array<DataType, SIZE> buffer;
|
||||
std::thread consumer;
|
||||
std::condition_variable cv;
|
||||
};
|
||||
|
||||
} // namespace counters
|
||||
} // namespace rocprofiler
|
||||
Référencer dans un nouveau ticket
Bloquer un utilisateur