diff --git a/inc/rocprofiler.h b/inc/rocprofiler.h index 31082cf48b..0254e31493 100644 --- a/inc/rocprofiler.h +++ b/inc/rocprofiler.h @@ -262,6 +262,10 @@ hsa_status_t rocprofiler_set_queue_callbacks( // Remove queue callbacks hsa_status_t rocprofiler_remove_queue_callbacks(); +// Start/stop queue callbacks +hsa_status_t rocprofiler_start_queue_callbacks(); +hsa_status_t rocprofiler_stop_queue_callbacks(); + //////////////////////////////////////////////////////////////////////////////// // Start/stop profiling // diff --git a/src/core/intercept_queue.cpp b/src/core/intercept_queue.cpp index 91028f739d..c09ef40c07 100644 --- a/src/core/intercept_queue.cpp +++ b/src/core/intercept_queue.cpp @@ -29,10 +29,9 @@ void InterceptQueue::HsaIntercept(HsaApiTable* table) { } InterceptQueue::mutex_t InterceptQueue::mutex_; -rocprofiler_callback_t InterceptQueue::dispatch_callback_ = NULL; -InterceptQueue::queue_callback_t InterceptQueue::create_callback_ = NULL; -InterceptQueue::queue_callback_t InterceptQueue::destroy_callback_ = NULL; +rocprofiler_queue_callbacks_t InterceptQueue::callbacks_ = {}; void* InterceptQueue::callback_data_ = NULL; +std::atomic InterceptQueue::dispatch_callback_{NULL}; InterceptQueue::obj_map_t* InterceptQueue::obj_map_ = NULL; const char* InterceptQueue::kernel_none_ = ""; Tracker* InterceptQueue::tracker_ = NULL; diff --git a/src/core/intercept_queue.h b/src/core/intercept_queue.h index f639b3e525..699fdc939b 100644 --- a/src/core/intercept_queue.h +++ b/src/core/intercept_queue.h @@ -84,8 +84,8 @@ class InterceptQueue { obj->queue_id = current_queue_id; ++current_queue_id; - if (create_callback_ != NULL) { - status = create_callback_(*queue, callback_data_); + if (callbacks_.create != NULL) { + status = callbacks_.create(*queue, callback_data_); } in_create_call_ = false; @@ -112,8 +112,8 @@ class InterceptQueue { std::lock_guard lck(mutex_); hsa_status_t status = HSA_STATUS_SUCCESS; - if (destroy_callback_ != NULL) { - status = destroy_callback_(queue, callback_data_); + if (callbacks_.destroy != NULL) { + status = callbacks_.destroy(queue, callback_data_); } if (status == HSA_STATUS_SUCCESS) { @@ -135,7 +135,8 @@ class InterceptQueue { bool to_submit = true; // Checking for dispatch packet type - if ((GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) && (dispatch_callback_ != NULL)) { + if ((GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) && + (dispatch_callback_.load(std::memory_order_acquire) != NULL)) { const hsa_kernel_dispatch_packet_t* dispatch_packet = reinterpret_cast(packet); const hsa_signal_t completion_signal = dispatch_packet->completion_signal; @@ -154,8 +155,7 @@ class InterceptQueue { const uint16_t kernel_object_flag = *((uint64_t*)kernel_code + 1); if (kernel_object_flag == 0) { if (!util::HsaRsrcFactory::IsExecutableTracking()) { - fprintf(stderr, "Error: V3 code object detected - code objects tracking should be enabled\n"); - abort(); + EXC_ABORT(HSA_STATUS_ERROR, "Error: V3 code object detected - code objects tracking should be enabled\n"); } } const char* kernel_name = (util::HsaRsrcFactory::IsExecutableTracking()) ? @@ -227,18 +227,25 @@ class InterceptQueue { } } - static void SetCallbacks(rocprofiler_callback_t dispatch_callback, - queue_callback_t create_callback, - queue_callback_t destroy_callback, - void* data) - { + static void SetCallbacks(rocprofiler_queue_callbacks_t callbacks, void* data) { std::lock_guard lck(mutex_); + if (callback_data_ != NULL) { + EXC_ABORT(HSA_STATUS_ERROR, "reassigning queue callbacks - not supported"); + } + callbacks_ = callbacks; callback_data_ = data; - dispatch_callback_ = dispatch_callback; - create_callback_ = create_callback; - destroy_callback_ = destroy_callback; + Start(); } + static void RemoveCallbacks() { + std::lock_guard lck(mutex_); + callbacks_ = {}; + Stop(); + } + + static inline void Start() { dispatch_callback_.store(callbacks_.dispatch, std::memory_order_release); } + static inline void Stop() { dispatch_callback_.store(NULL, std::memory_order_relaxed); } + static void TrackerOn(bool on) { tracker_on_ = on; } static bool IsTrackerOn() { return tracker_on_; } @@ -324,12 +331,13 @@ class InterceptQueue { ProxyQueue::Destroy(proxy_); } - static mutex_t mutex_; static const packet_word_t header_type_mask = (1ul << HSA_PACKET_HEADER_WIDTH_TYPE) - 1; - static rocprofiler_callback_t dispatch_callback_; - static queue_callback_t create_callback_; - static queue_callback_t destroy_callback_; + + static mutex_t mutex_; + static rocprofiler_queue_callbacks_t callbacks_; static void* callback_data_; + static std::atomic dispatch_callback_; + static obj_map_t* obj_map_; static const char* kernel_none_; static Tracker* tracker_; diff --git a/src/core/rocprofiler.cpp b/src/core/rocprofiler.cpp index 3f1362a71e..3a89f3315a 100644 --- a/src/core/rocprofiler.cpp +++ b/src/core/rocprofiler.cpp @@ -617,14 +617,26 @@ PUBLIC_API hsa_status_t rocprofiler_get_metrics(const rocprofiler_t* handle) { // Set/remove queue callbacks PUBLIC_API hsa_status_t rocprofiler_set_queue_callbacks(rocprofiler_queue_callbacks_t callbacks, void* data) { API_METHOD_PREFIX - rocprofiler::InterceptQueue::SetCallbacks(callbacks.dispatch, callbacks.create, callbacks.destroy, data); + rocprofiler::InterceptQueue::SetCallbacks(callbacks, data); API_METHOD_SUFFIX } // Remove queue callbacks PUBLIC_API hsa_status_t rocprofiler_remove_queue_callbacks() { API_METHOD_PREFIX - rocprofiler::InterceptQueue::SetCallbacks(NULL, NULL, NULL, NULL); + rocprofiler::InterceptQueue::RemoveCallbacks(); + API_METHOD_SUFFIX +} + +// Start/stop queue callbacks +hsa_status_t rocprofiler_start_queue_callbacks() { + API_METHOD_PREFIX + rocprofiler::InterceptQueue::Start(); + API_METHOD_SUFFIX +} +hsa_status_t rocprofiler_stop_queue_callbacks() { + API_METHOD_PREFIX + rocprofiler::InterceptQueue::Stop(); API_METHOD_SUFFIX }