Skip to content

Commit

Permalink
[L0] Use only a shared lock during queue sync calls
Browse files Browse the repository at this point in the history
Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
  • Loading branch information
nrspruit committed Apr 3, 2024
1 parent a0f3c51 commit 0086401
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
6 changes: 4 additions & 2 deletions source/adapters/level_zero/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueEventsWait(
//
// TODO: find a way to do that without blocking the host.

// Lock automatically releases when this goes out of scope.
std::scoped_lock<ur_shared_mutex> lock(Queue->Mutex);
std::unique_lock<ur_shared_mutex> QueueLock(Queue->Mutex, std::defer_lock);
QueueLock.lock();

if (OutEvent) {
UR_CALL(createEventAndAssociateQueue(Queue, OutEvent,
Expand All @@ -123,7 +123,9 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueEventsWait(
/* IsInternal */ false));
}

QueueLock.unlock();
UR_CALL(Queue->synchronize());
QueueLock.lock();

if (OutEvent) {
Queue->LastCommandEvent = reinterpret_cast<ur_event_handle_t>(*OutEvent);
Expand Down
31 changes: 22 additions & 9 deletions source/adapters/level_zero/queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueRelease(

std::vector<ur_event_handle_t> EventListToCleanup;
{
std::scoped_lock<ur_shared_mutex> Lock(Queue->Mutex);
std::unique_lock<ur_shared_mutex> QueueLock(Queue->Mutex, std::defer_lock);
QueueLock.lock();

if ((--Queue->RefCountExternal) != 0)
return UR_RESULT_SUCCESS;
Expand All @@ -410,8 +411,11 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueRelease(
auto Res = Queue->executeAllOpenCommandLists();

// Make sure all commands get executed.
if (Res == UR_RESULT_SUCCESS)
if (Res == UR_RESULT_SUCCESS) {
QueueLock.unlock();
UR_CALL(Queue->synchronize());
QueueLock.lock();
}

// Destroy all the fences created associated with this queue.
for (auto it = Queue->CommandListMap.begin();
Expand Down Expand Up @@ -624,9 +628,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueFinish(
ur_queue_handle_t UrQueue ///< [in] handle of the queue to be finished.
) {
if (UrQueue->UsingImmCmdLists) {
// Lock automatically releases when this goes out of scope.
std::scoped_lock<ur_shared_mutex> Lock(UrQueue->Mutex);

UR_CALL(UrQueue->synchronize());
} else {
std::unique_lock<ur_shared_mutex> Lock(UrQueue->Mutex);
Expand Down Expand Up @@ -1391,16 +1392,22 @@ ur_result_t CleanupEventListFromResetCmdList(
// runtime. Need to investigate whether relase can be done earlier, at sync
// points such as this, to reduce total number of active Events.
ur_result_t ur_queue_handle_t_::synchronize() {
if (!Healthy)
// std::shared_lock<ur_shared_mutex> QueueLock(this->Mutex);
this->Mutex.lock();
if (!Healthy) {
this->Mutex.unlock();
return UR_RESULT_SUCCESS;
}

auto syncImmCmdList = [](ur_queue_handle_t_ *Queue,
ur_command_list_ptr_t ImmCmdList) {
if (ImmCmdList == Queue->CommandListMap.end())
return UR_RESULT_SUCCESS;

// wait for all commands previously submitted to this immediate command list
ZE2UR_CALL(zeCommandListHostSynchronize, (ImmCmdList->first, UINT64_MAX));
Queue->Mutex.unlock();
ZE2UR_CALL(zeCommandListHostSynchronize, (ImmCmdList->first, UINT64_MAX));\
Queue->Mutex.lock();

// Cleanup all events from the synced command list.
CleanupEventListFromResetCmdList(ImmCmdList->second.EventList, true);
Expand Down Expand Up @@ -1441,8 +1448,11 @@ ur_result_t ur_queue_handle_t_::synchronize() {
UR_CALL(syncImmCmdList(this, ImmCmdList));
} else {
for (auto &ZeQueue : QueueGroup.second.ZeQueues)
if (ZeQueue)
if (ZeQueue) {
this->Mutex.unlock();
ZE2UR_CALL(zeHostSynchronize, (ZeQueue));
this->Mutex.lock();
}
}
}
}
Expand All @@ -1452,9 +1462,12 @@ ur_result_t ur_queue_handle_t_::synchronize() {

// With the entire queue synchronized, the active barriers must be done so we
// can remove them.
if (auto Res = ActiveBarriers.clear())
if (auto Res = ActiveBarriers.clear()) {
this->Mutex.unlock();
return Res;
}

this->Mutex.unlock();
return UR_RESULT_SUCCESS;
}

Expand Down

0 comments on commit 0086401

Please sign in to comment.