diff --git a/sycl/plugins/level_zero/pi_level_zero.cpp b/sycl/plugins/level_zero/pi_level_zero.cpp index fa277818d0f0a..7d9ac0e7ff729 100644 --- a/sycl/plugins/level_zero/pi_level_zero.cpp +++ b/sycl/plugins/level_zero/pi_level_zero.cpp @@ -3155,19 +3155,28 @@ pi_result piQueueFinish(pi_queue Queue) { // Wait until command lists attached to the command queue are executed. PI_ASSERT(Queue, PI_INVALID_QUEUE); - // Lock automatically releases when this goes out of scope. - std::lock_guard lock(Queue->PiQueueMutex); + std::vector ZeQueues; + { + // Lock automatically releases when this goes out of scope. + std::lock_guard lock(Queue->PiQueueMutex); - // execute any command list that may still be open. - if (auto Res = Queue->executeAllOpenCommandLists()) - return Res; + // execute any command list that may still be open. + if (auto Res = Queue->executeAllOpenCommandLists()) + return Res; - ZE_CALL(zeHostSynchronize, (Queue->ZeComputeCommandQueue)); - for (uint32_t i = 0; i < Queue->ZeCopyCommandQueues.size(); ++i) { - if (Queue->ZeCopyCommandQueues[i]) - ZE_CALL(zeHostSynchronize, (Queue->ZeCopyCommandQueues[i])); + ZeQueues = Queue->ZeCopyCommandQueues; + ZeQueues.push_back(Queue->ZeComputeCommandQueue); } + // Don't hold a lock to the queue's mutex while waiting. + // This allows continue working with the queue from other threads. + for (auto ZeQueue : ZeQueues) { + if (ZeQueue) + ZE_CALL(zeHostSynchronize, (ZeQueue)); + } + + // Lock automatically releases when this goes out of scope. + std::lock_guard lock(Queue->PiQueueMutex); // Prevent unneeded already finished events to show up in the wait list. Queue->LastCommandEvent = nullptr;