@@ -491,6 +491,8 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &Pool,
491
491
}
492
492
493
493
pi_result _pi_context::decrementUnreleasedEventsInPool (pi_event Event) {
494
+ std::shared_lock EventLock (Event->Mutex , std::defer_lock);
495
+ std::scoped_lock LockAll (ZeEventPoolCacheMutex, EventLock);
494
496
if (!Event->ZeEventPool ) {
495
497
// This must be an interop event created on a users's pool.
496
498
// Do nothing.
@@ -501,7 +503,6 @@ pi_result _pi_context::decrementUnreleasedEventsInPool(pi_event Event) {
501
503
getZeEventPoolCache (Event->isHostVisible (), Event->isProfilingEnabled ());
502
504
503
505
// Put the empty pool to the cache of the pools.
504
- std::lock_guard<std::mutex> Lock (ZeEventPoolCacheMutex);
505
506
if (NumEventsUnreleasedInEventPool[Event->ZeEventPool ] == 0 )
506
507
die (" Invalid event release: event pool doesn't have unreleased events" );
507
508
if (--NumEventsUnreleasedInEventPool[Event->ZeEventPool ] == 0 ) {
@@ -1148,7 +1149,10 @@ pi_result resetCommandLists(pi_queue Queue) {
1148
1149
for (auto Event : EventListToCleanup) {
1149
1150
// We don't need to synchronize the events since the fence
1150
1151
// synchronized above already does that.
1151
- Event->Completed = true ;
1152
+ {
1153
+ std::scoped_lock EventLock (Event->Mutex );
1154
+ Event->Completed = true ;
1155
+ }
1152
1156
PI_CALL (CleanupCompletedEvent (Event));
1153
1157
// This event was removed from the command list, so decrement ref count
1154
1158
// (it was incremented when they were added to the command list).
@@ -1445,6 +1449,7 @@ pi_result _pi_queue::executeCommandList(pi_command_list_ptr_t CommandList,
1445
1449
// Update each command's event in the command-list to "see" this
1446
1450
// proxy event as a host-visible counterpart.
1447
1451
for (auto &Event : CommandList->second .EventList ) {
1452
+ std::scoped_lock EventLock (Event->Mutex );
1448
1453
if (!Event->HostVisibleEvent ) {
1449
1454
Event->HostVisibleEvent = HostVisibleEvent;
1450
1455
PI_CALL (piEventRetain (HostVisibleEvent));
@@ -1693,17 +1698,20 @@ pi_result _pi_ze_event_list_t::createAndRetainPiZeEventList(
1693
1698
if (EventListLength > 0 ) {
1694
1699
for (pi_uint32 I = 0 ; I < EventListLength; I++) {
1695
1700
PI_ASSERT (EventList[I] != nullptr , PI_INVALID_VALUE);
1696
- if (EventList[I]->Completed )
1697
- continue ;
1698
-
1699
- // Poll of the host-visible events.
1700
- auto HostVisibleEvent = EventList[I]->HostVisibleEvent ;
1701
- if (FilterEventWaitList && HostVisibleEvent) {
1702
- auto Res =
1703
- ZE_CALL_NOCHECK (zeEventQueryStatus, (HostVisibleEvent->ZeEvent ));
1704
- if (Res == ZE_RESULT_SUCCESS) {
1705
- // Event has already completed, don't put it into the list
1701
+ {
1702
+ std::shared_lock Lock (EventList[I]->Mutex );
1703
+ if (EventList[I]->Completed )
1706
1704
continue ;
1705
+
1706
+ // Poll of the host-visible events.
1707
+ auto HostVisibleEvent = EventList[I]->HostVisibleEvent ;
1708
+ if (FilterEventWaitList && HostVisibleEvent) {
1709
+ auto Res = ZE_CALL_NOCHECK (zeEventQueryStatus,
1710
+ (HostVisibleEvent->ZeEvent ));
1711
+ if (Res == ZE_RESULT_SUCCESS) {
1712
+ // Event has already completed, don't put it into the list
1713
+ continue ;
1714
+ }
1707
1715
}
1708
1716
}
1709
1717
@@ -1758,6 +1766,7 @@ pi_result _pi_ze_event_list_t::createAndRetainPiZeEventList(
1758
1766
}
1759
1767
}
1760
1768
1769
+ std::shared_lock Lock (EventList[I]->Mutex );
1761
1770
this ->ZeEventList [TmpListLength] = EventList[I]->ZeEvent ;
1762
1771
this ->PiEventList [TmpListLength] = EventList[I];
1763
1772
TmpListLength += 1 ;
@@ -1780,6 +1789,7 @@ pi_result _pi_ze_event_list_t::createAndRetainPiZeEventList(
1780
1789
OpenCommandList->second .isCopy (CurQueue)))
1781
1790
return Res;
1782
1791
}
1792
+ std::shared_lock Lock (CurQueue->LastCommandEvent ->Mutex );
1783
1793
this ->ZeEventList [TmpListLength] = CurQueue->LastCommandEvent ->ZeEvent ;
1784
1794
this ->PiEventList [TmpListLength] = CurQueue->LastCommandEvent ;
1785
1795
TmpListLength += 1 ;
@@ -3370,7 +3380,10 @@ pi_result piQueueRelease(pi_queue Queue) {
3370
3380
for (auto Event : EventListToCleanup) {
3371
3381
// We don't need to synchronize the events since the queue
3372
3382
// synchronized above already does that.
3373
- Event->Completed = true ;
3383
+ {
3384
+ std::scoped_lock EventLock (Event->Mutex );
3385
+ Event->Completed = true ;
3386
+ }
3374
3387
PI_CALL (CleanupCompletedEvent (Event));
3375
3388
// This event was removed from the command list, so decrement ref count
3376
3389
// (it was incremented when they were added to the command list).
@@ -5187,6 +5200,9 @@ pi_result piextKernelGetNativeHandle(pi_kernel Kernel,
5187
5200
//
5188
5201
pi_result
5189
5202
_pi_event::getOrCreateHostVisibleEvent (ze_event_handle_t &ZeHostVisibleEvent) {
5203
+ PI_ASSERT (Queue, PI_INVALID_EVENT);
5204
+
5205
+ std::scoped_lock Lock (Queue->Mutex , this ->Mutex );
5190
5206
5191
5207
if (!HostVisibleEvent) {
5192
5208
if (EventsScope != OnDemandHostVisibleProxy)
@@ -5197,32 +5213,28 @@ _pi_event::getOrCreateHostVisibleEvent(ze_event_handle_t &ZeHostVisibleEvent) {
5197
5213
// proxy is created.
5198
5214
//
5199
5215
// Get a new command list to be used on this call
5200
- {
5201
- std::scoped_lock Lock (Queue->Mutex );
5202
5216
5203
- // We want to batch these commands to avoid extra submissions (costly)
5204
- bool OkToBatch = true ;
5217
+ // We want to batch these commands to avoid extra submissions (costly)
5218
+ bool OkToBatch = true ;
5205
5219
5206
- pi_command_list_ptr_t CommandList{};
5207
- if (auto Res = Queue->Context ->getAvailableCommandList (
5208
- Queue, CommandList, false /* UseCopyEngine */ , OkToBatch))
5209
- return Res;
5220
+ pi_command_list_ptr_t CommandList{};
5221
+ if (auto Res = Queue->Context ->getAvailableCommandList (
5222
+ Queue, CommandList, false /* UseCopyEngine */ , OkToBatch))
5223
+ return Res;
5210
5224
5211
- // Create a "proxy" host-visible event.
5212
- auto Res = createEventAndAssociateQueue (
5213
- Queue, &HostVisibleEvent, PI_COMMAND_TYPE_USER, CommandList, true );
5214
- // HostVisibleEvent->CleanedUp = true;
5215
- if (Res != PI_SUCCESS)
5216
- return Res;
5225
+ // Create a "proxy" host-visible event.
5226
+ auto Res = createEventAndAssociateQueue (
5227
+ Queue, &HostVisibleEvent, PI_COMMAND_TYPE_USER, CommandList, true );
5228
+ // HostVisibleEvent->CleanedUp = true;
5229
+ if (Res != PI_SUCCESS)
5230
+ return Res;
5217
5231
5218
- ZE_CALL (zeCommandListAppendWaitOnEvents,
5219
- (CommandList->first , 1 , &ZeEvent));
5220
- ZE_CALL (zeCommandListAppendSignalEvent,
5221
- (CommandList->first , HostVisibleEvent->ZeEvent ));
5232
+ ZE_CALL (zeCommandListAppendWaitOnEvents, (CommandList->first , 1 , &ZeEvent));
5233
+ ZE_CALL (zeCommandListAppendSignalEvent,
5234
+ (CommandList->first , HostVisibleEvent->ZeEvent ));
5222
5235
5223
- if (auto Res = Queue->executeCommandList (CommandList, false , OkToBatch))
5224
- return Res;
5225
- }
5236
+ if (auto Res = Queue->executeCommandList (CommandList, false , OkToBatch))
5237
+ return Res;
5226
5238
}
5227
5239
5228
5240
ZeHostVisibleEvent = HostVisibleEvent->ZeEvent ;
@@ -5297,12 +5309,18 @@ pi_result piEventGetInfo(pi_event Event, pi_event_info ParamName,
5297
5309
5298
5310
ReturnHelper ReturnValue (ParamValueSize, ParamValue, ParamValueSizeRet);
5299
5311
switch (ParamName) {
5300
- case PI_EVENT_INFO_COMMAND_QUEUE:
5312
+ case PI_EVENT_INFO_COMMAND_QUEUE: {
5313
+ std::shared_lock EventLock (Event->Mutex );
5301
5314
return ReturnValue (pi_queue{Event->Queue });
5302
- case PI_EVENT_INFO_CONTEXT:
5315
+ }
5316
+ case PI_EVENT_INFO_CONTEXT: {
5317
+ std::shared_lock EventLock (Event->Mutex );
5303
5318
return ReturnValue (pi_context{Event->Context });
5304
- case PI_EVENT_INFO_COMMAND_TYPE:
5319
+ }
5320
+ case PI_EVENT_INFO_COMMAND_TYPE: {
5321
+ std::shared_lock EventLock (Event->Mutex );
5305
5322
return ReturnValue (pi_cast<pi_uint64>(Event->CommandType ));
5323
+ }
5306
5324
case PI_EVENT_INFO_COMMAND_EXECUTION_STATUS: {
5307
5325
// Check to see if the event's Queue has an open command list due to
5308
5326
// batching. If so, go ahead and close and submit it, because it is
@@ -5329,6 +5347,7 @@ pi_result piEventGetInfo(pi_event Event, pi_event_info ParamName,
5329
5347
// Make sure that we query a host-visible event only.
5330
5348
// If one wasn't yet created then don't create it here as well, and
5331
5349
// just conservatively return that event is not yet completed.
5350
+ std::shared_lock EventLock (Event->Mutex );
5332
5351
auto HostVisibleEvent = Event->HostVisibleEvent ;
5333
5352
if (Event->Completed ) {
5334
5353
Result = CL_COMPLETE;
@@ -5359,6 +5378,7 @@ pi_result piEventGetProfilingInfo(pi_event Event, pi_profiling_info ParamName,
5359
5378
5360
5379
PI_ASSERT (Event, PI_INVALID_EVENT);
5361
5380
5381
+ std::shared_lock EventLock (Event->Mutex );
5362
5382
if (Event->Queue &&
5363
5383
(Event->Queue ->Properties & PI_QUEUE_PROFILING_ENABLE) == 0 ) {
5364
5384
return PI_PROFILING_INFO_NOT_AVAILABLE;
@@ -5549,18 +5569,20 @@ pi_result piEventsWait(pi_uint32 NumEvents, const pi_event *EventList) {
5549
5569
}
5550
5570
std::unordered_set<pi_queue> Queues;
5551
5571
for (uint32_t I = 0 ; I < NumEvents; I++) {
5552
- if (!EventList[I]->Completed ) {
5553
- auto HostVisibleEvent = EventList[I]->HostVisibleEvent ;
5554
- if (!HostVisibleEvent)
5555
- die (" The host-visible proxy event missing" );
5572
+ {
5573
+ std::shared_lock EventLock (EventList[I]->Mutex );
5574
+ if (!EventList[I]->Completed ) {
5575
+ auto HostVisibleEvent = EventList[I]->HostVisibleEvent ;
5576
+ if (!HostVisibleEvent)
5577
+ die (" The host-visible proxy event missing" );
5556
5578
5557
- ze_event_handle_t ZeEvent = HostVisibleEvent->ZeEvent ;
5558
- zePrint (" ZeEvent = %#lx\n " , pi_cast<std::uintptr_t >(ZeEvent));
5559
- ZE_CALL (zeHostSynchronize, (ZeEvent));
5579
+ ze_event_handle_t ZeEvent = HostVisibleEvent->ZeEvent ;
5580
+ zePrint (" ZeEvent = %#lx\n " , pi_cast<std::uintptr_t >(ZeEvent));
5581
+ ZE_CALL (zeHostSynchronize, (ZeEvent));
5582
+ }
5583
+ if (auto Q = EventList[I]->Queue )
5584
+ Queues.insert (Q);
5560
5585
}
5561
- if (auto Q = EventList[I]->Queue )
5562
- Queues.insert (Q);
5563
-
5564
5586
// NOTE: we are cleaning up after the event here to free resources
5565
5587
// sooner in case run-time is not calling piEventRelease soon enough.
5566
5588
CleanupCompletedEvent (EventList[I]);
@@ -5644,9 +5666,11 @@ pi_result piextEventGetNativeHandle(pi_event Event,
5644
5666
PI_ASSERT (Event, PI_INVALID_EVENT);
5645
5667
PI_ASSERT (NativeHandle, PI_INVALID_VALUE);
5646
5668
5647
- auto *ZeEvent = pi_cast<ze_event_handle_t *>(NativeHandle);
5648
- *ZeEvent = Event->ZeEvent ;
5649
-
5669
+ {
5670
+ std::shared_lock Lock (Event->Mutex );
5671
+ auto *ZeEvent = pi_cast<ze_event_handle_t *>(NativeHandle);
5672
+ *ZeEvent = Event->ZeEvent ;
5673
+ }
5650
5674
// Event can potentially be in an open command-list, make sure that
5651
5675
// it is submitted for execution to avoid potential deadlock if
5652
5676
// interop app is going to wait for it.
0 commit comments