@@ -335,15 +335,16 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &ZePool,
335
335
if ((ZeEventPool == nullptr ) ||
336
336
(NumEventsAvailableInEventPool[ZeEventPool] == 0 )) {
337
337
// Creation of the new ZePool with record in NumEventsAvailableInEventPool
338
- // and initialization of the record in NumEventsLiveInEventPool must be done
339
- // atomically. Otherwise it is possible that decrementAliveEventsInPool will
340
- // be called for the record in NumEventsLiveInEventPool before its
338
+ // and initialization of the record in NumEventsUnreleasedInEventPool must
339
+ // be done atomically. Otherwise it is possible that
340
+ // decrementUnreleasedEventsInPool will be called for the record in
341
+ // NumEventsUnreleasedInEventPool before its
341
342
std::lock (NumEventsAvailableInEventPoolMutex,
342
- NumEventsLiveInEventPoolMutex );
343
+ NumEventsUnreleasedInEventPoolMutex );
343
344
std::lock_guard<std::mutex> NumEventsAvailableInEventPoolGuard (
344
345
NumEventsAvailableInEventPoolMutex, std::adopt_lock);
345
- std::lock_guard<std::mutex> NumEventsLiveInEventPoolGuard (
346
- NumEventsLiveInEventPoolMutex , std::adopt_lock);
346
+ std::lock_guard<std::mutex> NumEventsUnreleasedInEventPoolGuard (
347
+ NumEventsUnreleasedInEventPoolMutex , std::adopt_lock);
347
348
348
349
ZeStruct<ze_event_pool_desc_t > ZeEventPoolDesc;
349
350
ZeEventPoolDesc.count = MaxNumEventsPerPool;
@@ -362,7 +363,7 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &ZePool,
362
363
ZE_CALL (zeEventPoolCreate, (ZeContext, &ZeEventPoolDesc, ZeDevices.size (),
363
364
&ZeDevices[0 ], &ZeEventPool));
364
365
NumEventsAvailableInEventPool[ZeEventPool] = MaxNumEventsPerPool - 1 ;
365
- NumEventsLiveInEventPool [ZeEventPool] = MaxNumEventsPerPool;
366
+ NumEventsUnreleasedInEventPool [ZeEventPool] = MaxNumEventsPerPool;
366
367
} else {
367
368
std::lock_guard<std::mutex> NumEventsAvailableInEventPoolGuard (
368
369
NumEventsAvailableInEventPoolMutex);
@@ -373,12 +374,24 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &ZePool,
373
374
return PI_SUCCESS;
374
375
}
375
376
376
- pi_result
377
- _pi_context::decrementAliveEventsInPool ( ze_event_pool_handle_t ZePool) {
378
- std::lock_guard<std::mutex> Lock (NumEventsLiveInEventPoolMutex );
379
- --NumEventsLiveInEventPool [ZePool];
380
- if (NumEventsLiveInEventPool [ZePool] == 0 ) {
377
+ pi_result _pi_context::decrementUnreleasedEventsInPool (pi_event Event) {
378
+ ze_event_pool_handle_t ZePool = Event-> ZeEventPool ;
379
+ std::lock_guard<std::mutex> Lock (NumEventsUnreleasedInEventPoolMutex );
380
+ --NumEventsUnreleasedInEventPool [ZePool];
381
+ if (NumEventsUnreleasedInEventPool [ZePool] == 0 ) {
381
382
ZE_CALL (zeEventPoolDestroy, (ZePool));
383
+ // Nullify ZeEventPool pointer to indicate this pool is already destroyed
384
+ // because we will call ZeEventPoolDestroy() if ZeEventPool is not null
385
+ // in pi_context::finalize().
386
+ // Note that calling ZeEventPoolDestroy() for the already destroyed pool
387
+ // will cause a segmentation fault in L0.
388
+ // We need to check the equality below because it is possible that
389
+ // multiple pi_context::ZeEventPool can be created if all slots in the pool
390
+ // are already used up. So nullifying pi_context::ZeEventPool may point
391
+ // a different EventPool than Event->ZeEventPool.
392
+ if (ZeEventPool == Event->ZeEventPool )
393
+ ZeEventPool = nullptr ;
394
+ Event->ZeEventPool = nullptr ;
382
395
}
383
396
return PI_SUCCESS;
384
397
}
@@ -597,9 +610,9 @@ pi_result _pi_context::finalize() {
597
610
// This function is called when pi_context is deallocated, piContextRelase.
598
611
// There could be some memory that may have not been deallocated.
599
612
// For example, zeEventPool could be still alive.
600
- std::lock_guard<std::mutex> NumEventsLiveInEventPoolGuard (
601
- NumEventsLiveInEventPoolMutex );
602
- if (ZeEventPool && NumEventsLiveInEventPool[ZeEventPool] )
613
+ std::lock_guard<std::mutex> NumEventsUnreleasedInEventPoolGuard (
614
+ NumEventsUnreleasedInEventPoolMutex );
615
+ if (ZeEventPool)
603
616
ZE_CALL (zeEventPoolDestroy, (ZeEventPool));
604
617
605
618
// Destroy the command list used for initializations
@@ -4419,7 +4432,7 @@ pi_result piEventRelease(pi_event Event) {
4419
4432
ZE_CALL (zeEventDestroy, (Event->ZeEvent ));
4420
4433
4421
4434
auto Context = Event->Context ;
4422
- if (auto Res = Context->decrementAliveEventsInPool (Event-> ZeEventPool ))
4435
+ if (auto Res = Context->decrementUnreleasedEventsInPool (Event))
4423
4436
return Res;
4424
4437
4425
4438
// We intentionally incremented the reference counter when an event is
0 commit comments