Skip to content

Commit 4156f78

Browse files
[SYCL] Add more cleanup points close to the shutdown (#11119)
Previously we tried to release internal resources only when the last (likely main) thread exits. For multi threaded applications it could be not functional. e.g. threads are closed during module unload and when main thread exits - other threads are still alive. Adding logic to try non blocking release for every thread exit and blocking for the last one. --------- Signed-off-by: Tikhomirova, Kseniya <[email protected]>
1 parent ec54804 commit 4156f78

File tree

4 files changed

+16
-16
lines changed

4 files changed

+16
-16
lines changed

sycl/source/detail/global_handler.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,11 @@ class ObjectUsageCounter {
5252
if (!MModifyCounter)
5353
return;
5454

55+
LockGuard Guard(GlobalHandler::MSyclGlobalHandlerProtector);
5556
MCounter--;
56-
if (!MCounter) {
57-
LockGuard Guard(GlobalHandler::MSyclGlobalHandlerProtector);
58-
GlobalHandler *RTGlobalObjHandler = GlobalHandler::getInstancePtr();
59-
if (RTGlobalObjHandler) {
60-
RTGlobalObjHandler->prepareSchedulerToRelease();
61-
}
57+
GlobalHandler *RTGlobalObjHandler = GlobalHandler::getInstancePtr();
58+
if (RTGlobalObjHandler) {
59+
RTGlobalObjHandler->prepareSchedulerToRelease(!MCounter);
6260
}
6361
}
6462

@@ -142,7 +140,7 @@ void GlobalHandler::attachScheduler(Scheduler *Scheduler) {
142140
// The method is used in unit tests only. Do not protect with lock since
143141
// releaseResources will cause dead lock due to host queue release
144142
if (MScheduler.Inst)
145-
prepareSchedulerToRelease();
143+
prepareSchedulerToRelease(true);
146144
MScheduler.Inst.reset(Scheduler);
147145
}
148146

@@ -273,11 +271,13 @@ void GlobalHandler::unloadPlugins() {
273271
getPlugins().clear();
274272
}
275273

276-
void GlobalHandler::prepareSchedulerToRelease() {
274+
void GlobalHandler::prepareSchedulerToRelease(bool Blocking) {
277275
#ifndef _WIN32
278-
drainThreadPool();
276+
if (Blocking)
277+
drainThreadPool();
279278
if (MScheduler.Inst)
280-
MScheduler.Inst->releaseResources();
279+
MScheduler.Inst->releaseResources(Blocking ? BlockingT::BLOCKING
280+
: BlockingT::NON_BLOCKING);
281281
#endif
282282
}
283283

@@ -306,7 +306,7 @@ void shutdown() {
306306

307307
// Ensure neither host task is working so that no default context is accessed
308308
// upon its release
309-
Handler->prepareSchedulerToRelease();
309+
Handler->prepareSchedulerToRelease(true);
310310

311311
if (Handler->MHostTaskThreadPool.Inst)
312312
Handler->MHostTaskThreadPool.Inst->finishAndWait();

sycl/source/detail/global_handler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class GlobalHandler {
8080
void unloadPlugins();
8181
void releaseDefaultContexts();
8282
void drainThreadPool();
83-
void prepareSchedulerToRelease();
83+
void prepareSchedulerToRelease(bool Blocking);
8484

8585
void InitXPTI();
8686
void TraceEventXPTI(const char *Message);

sycl/source/detail/scheduler/scheduler.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,13 @@ Scheduler::Scheduler() {
405405

406406
Scheduler::~Scheduler() { DefaultHostQueue.reset(); }
407407

408-
void Scheduler::releaseResources() {
408+
void Scheduler::releaseResources(BlockingT Blocking) {
409409
// There might be some commands scheduled for post enqueue cleanup that
410410
// haven't been freed because of the graph mutex being locked at the time,
411411
// clean them up now.
412412
cleanupCommands({});
413413

414-
cleanupAuxiliaryResources(BlockingT::BLOCKING);
414+
cleanupAuxiliaryResources(Blocking);
415415
// We need loop since sometimes we may need new objects to be added to
416416
// deferred mem objects storage during cleanup. Known example is: we cleanup
417417
// existing deferred mem objects under write lock, during this process we
@@ -420,7 +420,7 @@ void Scheduler::releaseResources() {
420420
// with size only so all confitions for deferred release are satisfied) is
421421
// added to deferred mem obj storage. So we may end up with leak.
422422
while (!isDeferredMemObjectsEmpty())
423-
cleanupDeferredMemObjects(BlockingT::BLOCKING);
423+
cleanupDeferredMemObjects(Blocking);
424424
}
425425

426426
MemObjRecord *Scheduler::getMemObjRecord(const Requirement *const Req) {

sycl/source/detail/scheduler/scheduler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ class Scheduler {
461461

462462
Scheduler();
463463
~Scheduler();
464-
void releaseResources();
464+
void releaseResources(BlockingT Blocking = BlockingT::BLOCKING);
465465
bool isDeferredMemObjectsEmpty();
466466

467467
void enqueueCommandForCG(EventImplPtr NewEvent,

0 commit comments

Comments
 (0)