Refactor of DebugSession

- added ThreadHelper to handle closing thread
- renamed condition variable - to indicate API events use

Related-To: NEO-7019

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2022-05-30 14:24:47 +00:00
committed by Compute-Runtime-Automation
parent 608a1d39bc
commit 05b5e33bb9
4 changed files with 42 additions and 34 deletions

View File

@@ -6,6 +6,8 @@
*/
#pragma once
#include "shared/source/os_interface/os_thread.h"
#include "level_zero/core/source/debugger/debugger_l0.h"
#include "level_zero/tools/source/debug/eu_thread.h"
#include <level_zero/ze_api.h>
@@ -78,6 +80,24 @@ struct DebugSession : _zet_debug_session_handle_t {
ze_result_t sanityMemAccessThreadCheck(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc);
struct ThreadHelper {
void close() {
threadActive.store(false);
if (thread) {
while (!threadFinished.load()) {
thread->yield();
}
thread->join();
thread.reset();
}
}
std::unique_ptr<NEO::Thread> thread;
std::atomic<bool> threadActive{true};
std::atomic<bool> threadFinished{false};
};
protected:
DebugSession(const zet_debug_config_t &config, Device *device);
virtual void startAsyncThread() = 0;

View File

@@ -275,7 +275,7 @@ ze_result_t DebugSessionLinux::initialize() {
return ZE_RESULT_NOT_READY;
}
void *DebugSessionLinux::asyncThread(void *arg) {
void *DebugSessionLinux::asyncThreadFunction(void *arg) {
DebugSessionLinux *self = reinterpret_cast<DebugSessionLinux *>(arg);
PRINT_DEBUGGER_INFO_LOG("Debugger async thread start\n", "");
@@ -286,7 +286,7 @@ void *DebugSessionLinux::asyncThread(void *arg) {
event->type = PRELIM_DRM_I915_DEBUG_EVENT_READ;
event->flags = 0;
while (self->asyncThreadActive) {
while (self->asyncThread.threadActive) {
self->handleEventsAsync(event);
self->sendInterrupts();
@@ -295,25 +295,16 @@ void *DebugSessionLinux::asyncThread(void *arg) {
PRINT_DEBUGGER_INFO_LOG("Debugger async thread closing\n", "");
self->asyncThreadFinished.store(true);
self->asyncThread.threadFinished.store(true);
return nullptr;
}
void DebugSessionLinux::startAsyncThread() {
thread = NEO::Thread::create(asyncThread, reinterpret_cast<void *>(this));
asyncThread.thread = NEO::Thread::create(asyncThreadFunction, reinterpret_cast<void *>(this));
}
void DebugSessionLinux::closeAsyncThread() {
asyncThreadActive.store(false);
if (thread) {
while (!asyncThreadFinished.load()) {
thread->yield();
}
thread->join();
thread.reset();
}
asyncThread.close();
}
void DebugSessionLinux::handleEventsAsync(prelim_drm_i915_debug_event *event) {
@@ -643,7 +634,7 @@ ze_result_t DebugSessionLinux::readEvent(uint64_t timeout, zet_debug_event_t *ou
std::unique_lock<std::mutex> lock(asyncThreadMutex);
if (timeout > 0 && clientHandleToConnection[clientHandle]->apiEvents.size() == 0) {
readEventCondition.wait_for(lock, std::chrono::milliseconds(timeout));
apiEventCondition.wait_for(lock, std::chrono::milliseconds(timeout));
}
if (clientHandleToConnection[clientHandle]->apiEvents.size() > 0) {
@@ -651,7 +642,7 @@ ze_result_t DebugSessionLinux::readEvent(uint64_t timeout, zet_debug_event_t *ou
clientHandleToConnection[clientHandle]->apiEvents.pop();
return ZE_RESULT_SUCCESS;
}
} while (timeout == UINT64_MAX && asyncThreadActive);
} while (timeout == UINT64_MAX && asyncThread.threadActive);
return ZE_RESULT_NOT_READY;
}

View File

@@ -164,6 +164,7 @@ struct DebugSessionLinux : DebugSessionImp {
Stopped,
InterruptAll
};
MOCKABLE_VIRTUAL void handleEvent(prelim_drm_i915_debug_event *event);
bool checkAllEventsCollected();
ze_result_t readEventImp(prelim_drm_i915_debug_event *drmDebugEvent);
@@ -190,10 +191,10 @@ struct DebugSessionLinux : DebugSessionImp {
clientHandleToConnection[clientHandle]->apiEvents.push(debugEvent);
readEventCondition.notify_all();
apiEventCondition.notify_all();
}
static void *asyncThread(void *arg);
static void *asyncThreadFunction(void *arg);
void startAsyncThread() override;
void closeAsyncThread();
void handleEventsAsync(prelim_drm_i915_debug_event *event);
@@ -227,11 +228,9 @@ struct DebugSessionLinux : DebugSessionImp {
uint64_t getSbaBufferGpuVa(uint64_t memoryHandle);
void printContextVms();
std::atomic<bool> asyncThreadActive{true};
std::atomic<bool> asyncThreadFinished{false};
ThreadHelper asyncThread;
std::mutex asyncThreadMutex;
std::condition_variable readEventCondition;
std::unique_ptr<NEO::Thread> thread;
std::condition_variable apiEventCondition;
int fd = 0;
int ioctl(unsigned long request, void *arg);

View File

@@ -260,8 +260,7 @@ struct MockDebugSessionLinux : public L0::DebugSessionLinux {
using L0::DebugSessionImp::stateSaveAreaHeader;
using L0::DebugSessionImp::triggerEvents;
using L0::DebugSessionLinux::asyncThreadActive;
using L0::DebugSessionLinux::asyncThreadFinished;
using L0::DebugSessionLinux::asyncThread;
using L0::DebugSessionLinux::checkAllEventsCollected;
using L0::DebugSessionLinux::clientHandle;
using L0::DebugSessionLinux::clientHandleClosed;
@@ -288,7 +287,6 @@ struct MockDebugSessionLinux : public L0::DebugSessionLinux {
using L0::DebugSessionLinux::readSbaBuffer;
using L0::DebugSessionLinux::readStateSaveAreaHeader;
using L0::DebugSessionLinux::startAsyncThread;
using L0::DebugSessionLinux::thread;
using L0::DebugSessionLinux::threadControl;
using L0::DebugSessionLinux::ThreadControlCmd;
using L0::DebugSessionLinux::typeToRegsetDesc;
@@ -1337,7 +1335,7 @@ TEST_F(DebugApiLinuxTest, GivenDebugSessionWhenClosingConnectionThenSysCallClose
EXPECT_EQ(1u, NEO::SysCalls::closeFuncCalled);
EXPECT_EQ(10, NEO::SysCalls::closeFuncArgPassed);
EXPECT_FALSE(session->asyncThreadActive);
EXPECT_FALSE(session->asyncThread.threadActive);
NEO::SysCalls::closeFuncCalled = 0;
NEO::SysCalls::closeFuncArgPassed = 0;
@@ -5474,13 +5472,13 @@ TEST_F(DebugApiLinuxAsyncThreadTest, GivenDebugSessionWhenStartingAndClosingAsyn
while (handler->pollCounter == 0)
;
EXPECT_TRUE(session->asyncThreadActive);
EXPECT_FALSE(session->asyncThreadFinished);
EXPECT_TRUE(session->asyncThread.threadActive);
EXPECT_FALSE(session->asyncThread.threadFinished);
session->closeAsyncThread();
EXPECT_FALSE(session->asyncThreadActive);
EXPECT_TRUE(session->asyncThreadFinished);
EXPECT_FALSE(session->asyncThread.threadActive);
EXPECT_TRUE(session->asyncThread.threadFinished);
}
TEST_F(DebugApiLinuxAsyncThreadTest, GivenDebugSessionWithAsyncThreadWhenClosingConnectionThenAsyncThreadIsTerminated) {
@@ -5500,13 +5498,13 @@ TEST_F(DebugApiLinuxAsyncThreadTest, GivenDebugSessionWithAsyncThreadWhenClosing
while (handler->pollCounter == 0)
;
EXPECT_TRUE(session->asyncThreadActive);
EXPECT_FALSE(session->asyncThreadFinished);
EXPECT_TRUE(session->asyncThread.threadActive);
EXPECT_FALSE(session->asyncThread.threadFinished);
session->closeConnection();
EXPECT_FALSE(session->asyncThreadActive);
EXPECT_TRUE(session->asyncThreadFinished);
EXPECT_FALSE(session->asyncThread.threadActive);
EXPECT_TRUE(session->asyncThread.threadFinished);
}
TEST_F(DebugApiLinuxAsyncThreadTest, GivenNoEventsAvailableWithinTimeoutWhenReadingEventThenNotReadyReturned) {