control of trace buffer thread start
[ROCm/roctracer commit: f214221bb2]
Esse commit está contido em:
@@ -250,20 +250,14 @@ roctracer_status_t roctracer_get_timestamp(
|
||||
uint64_t* timestamp); // [out] return timestamp
|
||||
|
||||
// Load/Unload methods
|
||||
bool roctracer_load();
|
||||
void roctracer_unload();
|
||||
|
||||
// Set properties
|
||||
roctracer_status_t roctracer_set_properties(
|
||||
roctracer_domain_t domain, // tracing domain
|
||||
void* propertes); // tracing properties
|
||||
|
||||
typedef struct HsaApiTable HsaApiTable;
|
||||
bool roctracer_load(
|
||||
HsaApiTable* table,
|
||||
uint64_t runtime_version,
|
||||
uint64_t failed_tool_count,
|
||||
const char* const* failed_tool_names);
|
||||
|
||||
void roctracer_unload(bool destruct);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C" block
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -548,6 +548,7 @@ unsigned set_stopped(unsigned val) {
|
||||
} // namespace roctracer
|
||||
|
||||
LOADER_INSTANTIATE();
|
||||
TRACE_BUFFER_INSTANTIATE();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public library methods
|
||||
@@ -989,6 +990,7 @@ PUBLIC_API roctracer_status_t roctracer_flush_activity_expl(roctracer_pool_t* po
|
||||
if (pool == NULL) pool = roctracer_default_pool();
|
||||
roctracer::MemoryPool* memory_pool = reinterpret_cast<roctracer::MemoryPool*>(pool);
|
||||
memory_pool->Flush();
|
||||
roctracer::TraceBufferBase::FlushAll();
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
@@ -1045,6 +1047,12 @@ PUBLIC_API void roctracer_stop() {
|
||||
}
|
||||
}
|
||||
|
||||
PUBLIC_API roctracer_status_t roctracer_get_timestamp(uint64_t* timestamp) {
|
||||
API_METHOD_PREFIX
|
||||
*timestamp = util::HsaRsrcFactory::Instance().TimestampNs();
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
// Set properties
|
||||
PUBLIC_API roctracer_status_t roctracer_set_properties(
|
||||
roctracer_domain_t domain,
|
||||
@@ -1053,6 +1061,8 @@ PUBLIC_API roctracer_status_t roctracer_set_properties(
|
||||
API_METHOD_PREFIX
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_OPS: {
|
||||
roctracer::trace_buffer.StartWorkerThread();
|
||||
|
||||
// HSA OPS properties
|
||||
roctracer::hsa_ops_properties_t* ops_properties = reinterpret_cast<roctracer::hsa_ops_properties_t*>(properties);
|
||||
HsaApiTable* table = reinterpret_cast<HsaApiTable*>(ops_properties->table);
|
||||
@@ -1112,11 +1122,10 @@ PUBLIC_API roctracer_status_t roctracer_set_properties(
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
// HSA-runtime tool on-load method
|
||||
PUBLIC_API bool roctracer_load(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count,
|
||||
const char* const* failed_tool_names) {
|
||||
ONLOAD_TRACE_BEG();
|
||||
PUBLIC_API bool roctracer_load() {
|
||||
static bool is_loaded = false;
|
||||
ONLOAD_TRACE("begin, loaded(" << is_loaded << ")");
|
||||
|
||||
if (is_loaded) return true;
|
||||
is_loaded = true;
|
||||
|
||||
@@ -1124,11 +1133,10 @@ PUBLIC_API bool roctracer_load(HsaApiTable* table, uint64_t runtime_version, uin
|
||||
return true;
|
||||
}
|
||||
|
||||
PUBLIC_API void roctracer_unload(bool destruct) {
|
||||
PUBLIC_API void roctracer_unload() {
|
||||
static bool is_unloaded = false;
|
||||
ONLOAD_TRACE("begin (" << destruct << ", " << is_unloaded << ")");
|
||||
ONLOAD_TRACE("begin, unloaded(" << is_unloaded << ")");
|
||||
|
||||
if (destruct == false) return;
|
||||
if (is_unloaded == true) return;
|
||||
is_unloaded = true;
|
||||
|
||||
@@ -1137,23 +1145,16 @@ PUBLIC_API void roctracer_unload(bool destruct) {
|
||||
ONLOAD_TRACE_END();
|
||||
}
|
||||
|
||||
PUBLIC_API roctracer_status_t roctracer_get_timestamp(uint64_t* timestamp) {
|
||||
API_METHOD_PREFIX
|
||||
*timestamp = util::HsaRsrcFactory::Instance().TimestampNs();
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
// HSA-runtime tool on-load/unload methods
|
||||
PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count,
|
||||
const char* const* failed_tool_names) {
|
||||
ONLOAD_TRACE_BEG();
|
||||
const bool ret = roctracer_load(table, runtime_version, failed_tool_count, failed_tool_names);
|
||||
const bool ret = roctracer_load();
|
||||
ONLOAD_TRACE_END();
|
||||
return ret;
|
||||
}
|
||||
PUBLIC_API void OnUnload() {
|
||||
ONLOAD_TRACE_BEG();
|
||||
roctracer_unload(false);
|
||||
ONLOAD_TRACE_END();
|
||||
ONLOAD_TRACE("done");
|
||||
}
|
||||
|
||||
CONSTRUCTOR_API void constructor() {
|
||||
@@ -1166,7 +1167,7 @@ CONSTRUCTOR_API void constructor() {
|
||||
|
||||
DESTRUCTOR_API void destructor() {
|
||||
ONLOAD_TRACE_BEG();
|
||||
roctracer_unload(true);
|
||||
roctracer_unload();
|
||||
util::HsaRsrcFactory::Destroy();
|
||||
roctracer::util::Logger::Destroy();
|
||||
ONLOAD_TRACE_END();
|
||||
|
||||
@@ -2,12 +2,23 @@
|
||||
#define SRC_CORE_TRACE_BUFFER_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FATAL(stream) \
|
||||
do { \
|
||||
std::ostringstream oss; \
|
||||
oss << __FUNCTION__ << "(), " << stream; \
|
||||
std::cout << oss.str() << std::endl; \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
#define PTHREAD_CALL(call) \
|
||||
do { \
|
||||
int err = call; \
|
||||
@@ -53,8 +64,55 @@ struct trace_entry_t {
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct push_element_fun {
|
||||
T* const elem_;
|
||||
void fun(T* node) { if (node->next_elem_ == NULL) node->next_elem_ = elem_; }
|
||||
push_element_fun(T* elem) : elem_(elem) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct call_element_fun {
|
||||
void (T::*fptr_)();
|
||||
void fun(T* node) { (node->*fptr_)(); }
|
||||
call_element_fun(void (T::*f)()) : fptr_(f) {}
|
||||
};
|
||||
|
||||
struct TraceBufferBase {
|
||||
typedef std::mutex mutex_t;
|
||||
|
||||
virtual void StartWorkerThread() = 0;
|
||||
virtual void Flush() = 0;
|
||||
|
||||
static void StartWorkerThreadAll() { foreach(call_element_fun<TraceBufferBase>(&TraceBufferBase::StartWorkerThread)); }
|
||||
static void FlushAll() { foreach(call_element_fun<TraceBufferBase>(&TraceBufferBase::Flush)); }
|
||||
|
||||
static void Push(TraceBufferBase* elem) {
|
||||
if (head_elem_ == NULL) head_elem_ = elem;
|
||||
else foreach(push_element_fun<TraceBufferBase>(elem));
|
||||
}
|
||||
|
||||
TraceBufferBase() : next_elem_(NULL) {}
|
||||
|
||||
template<class F>
|
||||
static void foreach(const F& f_in) {
|
||||
std::lock_guard<mutex_t> lck(mutex_);
|
||||
F f = f_in;
|
||||
TraceBufferBase* p = head_elem_;
|
||||
while (p != NULL) {
|
||||
TraceBufferBase* next = p->next_elem_;
|
||||
f.fun(p);
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
|
||||
TraceBufferBase* next_elem_;
|
||||
static TraceBufferBase* head_elem_;
|
||||
static mutex_t mutex_;
|
||||
};
|
||||
|
||||
template <typename Entry>
|
||||
class TraceBuffer {
|
||||
class TraceBuffer : protected TraceBufferBase {
|
||||
public:
|
||||
typedef void (*callback_t)(Entry*);
|
||||
typedef TraceBuffer<Entry> Obj;
|
||||
@@ -67,7 +125,8 @@ class TraceBuffer {
|
||||
};
|
||||
|
||||
TraceBuffer(const char* name, uint32_t size, flush_prm_t* flush_prm_arr, uint32_t flush_prm_count) :
|
||||
is_flushed_(false)
|
||||
is_flushed_(false),
|
||||
work_thread_started_(false)
|
||||
{
|
||||
name_ = strdup(name);
|
||||
size_ = size;
|
||||
@@ -80,31 +139,43 @@ class TraceBuffer {
|
||||
flush_prm_arr_ = flush_prm_arr;
|
||||
flush_prm_count_ = flush_prm_count;
|
||||
|
||||
PTHREAD_CALL(pthread_mutex_init(&work_mutex_, NULL));
|
||||
PTHREAD_CALL(pthread_cond_init(&work_cond_, NULL));
|
||||
PTHREAD_CALL(pthread_create(&work_thread_, NULL, allocate_worker, this));
|
||||
TraceBufferBase::Push(this);
|
||||
}
|
||||
|
||||
~TraceBuffer() {
|
||||
PTHREAD_CALL(pthread_cancel(work_thread_));
|
||||
void *res;
|
||||
PTHREAD_CALL(pthread_join(work_thread_, &res));
|
||||
if (res != PTHREAD_CANCELED) abort_run("~TraceBuffer: consumer thread wasn't stopped correctly");
|
||||
|
||||
StopWorkerThread();
|
||||
Flush();
|
||||
}
|
||||
|
||||
void StartWorkerThread() {
|
||||
std::lock_guard<mutex_t> lck(mutex_);
|
||||
if (work_thread_started_ == false) {
|
||||
PTHREAD_CALL(pthread_mutex_init(&work_mutex_, NULL));
|
||||
PTHREAD_CALL(pthread_cond_init(&work_cond_, NULL));
|
||||
PTHREAD_CALL(pthread_create(&work_thread_, NULL, allocate_worker, this));
|
||||
work_thread_started_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void StopWorkerThread() {
|
||||
std::lock_guard<mutex_t> lck(mutex_);
|
||||
if (work_thread_started_ == true) {
|
||||
PTHREAD_CALL(pthread_cancel(work_thread_));
|
||||
void *res;
|
||||
PTHREAD_CALL(pthread_join(work_thread_, &res));
|
||||
if (res != PTHREAD_CANCELED) FATAL("consumer thread wasn't stopped correctly");
|
||||
work_thread_started_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
Entry* GetEntry() {
|
||||
const pointer_t pointer = read_pointer_.fetch_add(1);
|
||||
if (pointer >= end_pointer_) wrap_buffer(pointer);
|
||||
if (pointer >= end_pointer_) abort_run("pointer >= end_pointer_ after buffer wrap");
|
||||
if (pointer >= end_pointer_) FATAL("pointer >= end_pointer_ after buffer wrap");
|
||||
return data_ + (pointer + size_ - end_pointer_);
|
||||
}
|
||||
|
||||
void Flush() {
|
||||
flush_buf();
|
||||
}
|
||||
void Flush() { flush_buf(); }
|
||||
|
||||
private:
|
||||
void flush_buf() {
|
||||
@@ -134,7 +205,7 @@ class TraceBuffer {
|
||||
|
||||
inline Entry* allocate_fun() {
|
||||
Entry* ptr = (Entry*) malloc(size_ * sizeof(Entry));
|
||||
if (ptr == NULL) abort_run("TraceBuffer::allocate_fun: calloc failed");
|
||||
if (ptr == NULL) FATAL("malloc failed");
|
||||
//memset(ptr, 0, size_ * sizeof(Entry));
|
||||
return ptr;
|
||||
}
|
||||
@@ -156,24 +227,20 @@ class TraceBuffer {
|
||||
|
||||
void wrap_buffer(const pointer_t pointer) {
|
||||
std::lock_guard<mutex_t> lck(mutex_);
|
||||
if (work_thread_started_ == false) FATAL("worker thread is not started");
|
||||
|
||||
PTHREAD_CALL(pthread_mutex_lock(&work_mutex_));
|
||||
if (pointer >= end_pointer_) {
|
||||
data_ = next_;
|
||||
next_ = NULL;
|
||||
PTHREAD_CALL(pthread_cond_signal(&work_cond_));
|
||||
end_pointer_ += size_;
|
||||
if (end_pointer_ == 0) abort_run("TraceBuffer::wrap_buffer: pointer overflow");
|
||||
if (end_pointer_ == 0) FATAL("pointer overflow");
|
||||
buf_list_.push_back(data_);
|
||||
}
|
||||
PTHREAD_CALL(pthread_mutex_unlock(&work_mutex_));
|
||||
}
|
||||
|
||||
void abort_run(const char* str) {
|
||||
fprintf(stderr, "%s\n", str);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
const char* name_;
|
||||
uint32_t size_;
|
||||
Entry* data_;
|
||||
@@ -189,9 +256,14 @@ class TraceBuffer {
|
||||
pthread_t work_thread_;
|
||||
pthread_mutex_t work_mutex_;
|
||||
pthread_cond_t work_cond_;
|
||||
bool work_thread_started_;
|
||||
|
||||
mutex_t mutex_;
|
||||
};
|
||||
} // namespace roctracer
|
||||
|
||||
#define TRACE_BUFFER_INSTANTIATE() \
|
||||
roctracer::TraceBufferBase* roctracer::TraceBufferBase::head_elem_ = NULL; \
|
||||
roctracer::TraceBufferBase::mutex_t roctracer::TraceBufferBase::mutex_;
|
||||
|
||||
#endif // SRC_CORE_TRACE_BUFFER_H_
|
||||
|
||||
@@ -77,6 +77,7 @@ bool trace_hip_activity = false;
|
||||
bool trace_kfd = false;
|
||||
|
||||
LOADER_INSTANTIATE();
|
||||
TRACE_BUFFER_INSTANTIATE();
|
||||
|
||||
// Global output file handle
|
||||
FILE* roctx_file_handle = NULL;
|
||||
@@ -524,9 +525,55 @@ void close_output_file(FILE* file_handle) {
|
||||
if ((file_handle != NULL) && (file_handle != stdout)) fclose(file_handle);
|
||||
}
|
||||
|
||||
// tool unload method
|
||||
void tool_unload() {
|
||||
static bool is_unloaded = false;
|
||||
ONLOAD_TRACE("begin, unloaded(" << is_unloaded << ")");
|
||||
|
||||
if (is_unloaded == true) return;
|
||||
is_unloaded = true;
|
||||
|
||||
roctracer_unload();
|
||||
|
||||
if (trace_roctx) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_ROCTX));
|
||||
|
||||
roctx_trace_buffer.Flush();
|
||||
close_output_file(roctx_file_handle);
|
||||
}
|
||||
if (trace_hsa_api) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HSA_API));
|
||||
|
||||
hsa_api_trace_buffer.Flush();
|
||||
close_output_file(hsa_api_file_handle);
|
||||
}
|
||||
if (trace_hsa_activity) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HSA_OPS));
|
||||
|
||||
close_output_file(hsa_async_copy_file_handle);
|
||||
}
|
||||
if (trace_hip_api || trace_hip_activity) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HIP_API));
|
||||
ROCTRACER_CALL(roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HIP_API));
|
||||
ROCTRACER_CALL(roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HCC_OPS));
|
||||
ROCTRACER_CALL(roctracer_flush_activity());
|
||||
ROCTRACER_CALL(roctracer_close_pool());
|
||||
|
||||
hip_api_trace_buffer.Flush();
|
||||
close_output_file(hip_api_file_handle);
|
||||
close_output_file(hcc_activity_file_handle);
|
||||
}
|
||||
|
||||
if (trace_kfd) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_KFD_API));
|
||||
fclose(kfd_api_file_handle);
|
||||
}
|
||||
ONLOAD_TRACE_END();
|
||||
}
|
||||
|
||||
// HSA-runtime tool on-load method
|
||||
extern "C" PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count,
|
||||
const char* const* failed_tool_names) {
|
||||
const char* const* failed_tool_names) {
|
||||
ONLOAD_TRACE_BEG();
|
||||
timer = new hsa_rt_utils::Timer(table->core_->hsa_system_get_info_fn);
|
||||
|
||||
@@ -758,61 +805,15 @@ extern "C" PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version,
|
||||
printf(")\n");
|
||||
}
|
||||
|
||||
roctracer::TraceBufferBase::StartWorkerThreadAll();
|
||||
const bool ret = roctracer_load();
|
||||
ONLOAD_TRACE_END();
|
||||
return roctracer_load(table, runtime_version, failed_tool_count, failed_tool_names);
|
||||
}
|
||||
|
||||
// tool unload method
|
||||
void tool_unload(bool destruct) {
|
||||
static bool is_unloaded = false;
|
||||
ONLOAD_TRACE("begin (" << destruct <<", " << is_unloaded << ")");
|
||||
|
||||
if (destruct == false) return;
|
||||
if (is_unloaded == true) return;
|
||||
is_unloaded = true;
|
||||
roctracer_unload(destruct);
|
||||
|
||||
if (trace_roctx) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_ROCTX));
|
||||
|
||||
roctx_trace_buffer.Flush();
|
||||
close_output_file(roctx_file_handle);
|
||||
}
|
||||
if (trace_hsa_api) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HSA_API));
|
||||
|
||||
hsa_api_trace_buffer.Flush();
|
||||
close_output_file(hsa_api_file_handle);
|
||||
}
|
||||
if (trace_hsa_activity) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HSA_OPS));
|
||||
|
||||
close_output_file(hsa_async_copy_file_handle);
|
||||
}
|
||||
if (trace_hip_api || trace_hip_activity) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HIP_API));
|
||||
ROCTRACER_CALL(roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HIP_API));
|
||||
ROCTRACER_CALL(roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HCC_OPS));
|
||||
ROCTRACER_CALL(roctracer_flush_activity());
|
||||
ROCTRACER_CALL(roctracer_close_pool());
|
||||
|
||||
hip_api_trace_buffer.Flush();
|
||||
close_output_file(hip_api_file_handle);
|
||||
close_output_file(hcc_activity_file_handle);
|
||||
}
|
||||
|
||||
if (trace_kfd) {
|
||||
ROCTRACER_CALL(roctracer_disable_domain_callback(ACTIVITY_DOMAIN_KFD_API));
|
||||
fclose(kfd_api_file_handle);
|
||||
}
|
||||
ONLOAD_TRACE_END();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// HSA-runtime on-unload method
|
||||
extern "C" PUBLIC_API void OnUnload() {
|
||||
ONLOAD_TRACE_BEG();
|
||||
tool_unload(false);
|
||||
ONLOAD_TRACE_END();
|
||||
ONLOAD_TRACE("");
|
||||
}
|
||||
|
||||
extern "C" CONSTRUCTOR_API void constructor() {
|
||||
@@ -820,6 +821,6 @@ extern "C" CONSTRUCTOR_API void constructor() {
|
||||
}
|
||||
extern "C" DESTRUCTOR_API void destructor() {
|
||||
ONLOAD_TRACE_BEG();
|
||||
tool_unload(true);
|
||||
tool_unload();
|
||||
ONLOAD_TRACE_END();
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário