Skip to content

Commit 7fc8aa0

Browse files
author
sergei
authored
[SYCL] Introduce per-field lock in global handler (#4042)
Signed-off-by: Sergey Kanaev <[email protected]>
1 parent c69a311 commit 7fc8aa0

File tree

2 files changed

+41
-86
lines changed

2 files changed

+41
-86
lines changed

sycl/source/detail/global_handler.cpp

Lines changed: 25 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
__SYCL_INLINE_NAMESPACE(cl) {
2525
namespace sycl {
2626
namespace detail {
27+
using LockGuard = std::lock_guard<SpinLock>;
28+
2729
GlobalHandler::GlobalHandler() = default;
2830
GlobalHandler::~GlobalHandler() = default;
2931

@@ -32,109 +34,57 @@ GlobalHandler &GlobalHandler::instance() {
3234
return *SyclGlobalObjectsHandler;
3335
}
3436

35-
Scheduler &GlobalHandler::getScheduler() {
36-
if (MScheduler)
37-
return *MScheduler;
37+
template <typename T, typename... Types>
38+
T &GlobalHandler::getOrCreate(InstWithLock<T> &IWL, Types... Args) {
39+
const LockGuard Lock{IWL.Lock};
3840

39-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
40-
if (!MScheduler)
41-
MScheduler = std::make_unique<Scheduler>();
41+
if (!IWL.Inst)
42+
IWL.Inst = std::make_unique<T>(Args...);
4243

43-
return *MScheduler;
44+
return *IWL.Inst;
4445
}
45-
ProgramManager &GlobalHandler::getProgramManager() {
46-
if (MProgramManager)
47-
return *MProgramManager;
4846

49-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
50-
if (!MProgramManager)
51-
MProgramManager = std::make_unique<ProgramManager>();
47+
Scheduler &GlobalHandler::getScheduler() { return getOrCreate(MScheduler); }
5248

53-
return *MProgramManager;
49+
ProgramManager &GlobalHandler::getProgramManager() {
50+
return getOrCreate(MProgramManager);
5451
}
55-
Sync &GlobalHandler::getSync() {
56-
if (MSync)
57-
return *MSync;
5852

59-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
60-
if (!MSync)
61-
MSync = std::make_unique<Sync>();
53+
Sync &GlobalHandler::getSync() { return getOrCreate(MSync); }
6254

63-
return *MSync;
64-
}
6555
std::vector<PlatformImplPtr> &GlobalHandler::getPlatformCache() {
66-
if (MPlatformCache)
67-
return *MPlatformCache;
68-
69-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
70-
if (!MPlatformCache)
71-
MPlatformCache = std::make_unique<std::vector<PlatformImplPtr>>();
72-
73-
return *MPlatformCache;
56+
return getOrCreate(MPlatformCache);
7457
}
75-
std::mutex &GlobalHandler::getPlatformMapMutex() {
76-
if (MPlatformMapMutex)
77-
return *MPlatformMapMutex;
7858

79-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
80-
if (!MPlatformMapMutex)
81-
MPlatformMapMutex = std::make_unique<std::mutex>();
82-
83-
return *MPlatformMapMutex;
59+
std::mutex &GlobalHandler::getPlatformMapMutex() {
60+
return getOrCreate(MPlatformMapMutex);
8461
}
85-
std::mutex &GlobalHandler::getFilterMutex() {
86-
if (MFilterMutex)
87-
return *MFilterMutex;
88-
89-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
90-
if (!MFilterMutex)
91-
MFilterMutex = std::make_unique<std::mutex>();
9262

93-
return *MFilterMutex;
63+
std::mutex &GlobalHandler::getFilterMutex() {
64+
return getOrCreate(MFilterMutex);
9465
}
9566
std::vector<plugin> &GlobalHandler::getPlugins() {
96-
if (MPlugins)
97-
return *MPlugins;
98-
99-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
100-
if (!MPlugins)
101-
MPlugins = std::make_unique<std::vector<plugin>>();
102-
103-
return *MPlugins;
67+
return getOrCreate(MPlugins);
10468
}
10569
device_filter_list &
10670
GlobalHandler::getDeviceFilterList(const std::string &InitValue) {
107-
if (MDeviceFilterList)
108-
return *MDeviceFilterList;
109-
110-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
111-
if (!MDeviceFilterList)
112-
MDeviceFilterList = std::make_unique<device_filter_list>(InitValue);
113-
114-
return *MDeviceFilterList;
71+
return getOrCreate(MDeviceFilterList, InitValue);
11572
}
11673

11774
std::mutex &GlobalHandler::getHandlerExtendedMembersMutex() {
118-
if (MHandlerExtendedMembersMutex)
119-
return *MHandlerExtendedMembersMutex;
120-
121-
const std::lock_guard<SpinLock> Lock{MFieldsLock};
122-
if (!MHandlerExtendedMembersMutex)
123-
MHandlerExtendedMembersMutex = std::make_unique<std::mutex>();
124-
125-
return *MHandlerExtendedMembersMutex;
75+
return getOrCreate(MHandlerExtendedMembersMutex);
12676
}
12777

12878
void shutdown() {
12979
// First, release resources, that may access plugins.
130-
GlobalHandler::instance().MScheduler.reset(nullptr);
131-
GlobalHandler::instance().MProgramManager.reset(nullptr);
132-
GlobalHandler::instance().MPlatformCache.reset(nullptr);
80+
GlobalHandler::instance().MScheduler.Inst.reset(nullptr);
81+
GlobalHandler::instance().MProgramManager.Inst.reset(nullptr);
82+
GlobalHandler::instance().MPlatformCache.Inst.reset(nullptr);
13383

13484
// Call to GlobalHandler::instance().getPlugins() initializes plugins. If
13585
// user application has loaded SYCL runtime, and never called any APIs,
13686
// there's no need to load and unload plugins.
137-
if (GlobalHandler::instance().MPlugins) {
87+
if (GlobalHandler::instance().MPlugins.Inst) {
13888
for (plugin &Plugin : GlobalHandler::instance().getPlugins()) {
13989
// PluginParameter is reserved for future use that can control
14090
// some parameters in the plugin tear-down process.
@@ -143,7 +93,7 @@ void shutdown() {
14393
Plugin.call_nocheck<PiApiKind::piTearDown>(PluginParameter);
14494
Plugin.unload();
14595
}
146-
GlobalHandler::instance().MPlugins.reset(nullptr);
96+
GlobalHandler::instance().MPlugins.Inst.reset(nullptr);
14797
}
14898

14999
// Release the rest of global resources.

sycl/source/detail/global_handler.hpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,24 @@ class GlobalHandler {
6666
GlobalHandler();
6767
~GlobalHandler();
6868

69-
SpinLock MFieldsLock;
69+
template <typename T> struct InstWithLock {
70+
std::unique_ptr<T> Inst;
71+
SpinLock Lock;
72+
};
7073

71-
// Do not forget to update shutdown() function if needed.
72-
std::unique_ptr<Scheduler> MScheduler;
73-
std::unique_ptr<ProgramManager> MProgramManager;
74-
std::unique_ptr<Sync> MSync;
75-
std::unique_ptr<std::vector<PlatformImplPtr>> MPlatformCache;
76-
std::unique_ptr<std::mutex> MPlatformMapMutex;
77-
std::unique_ptr<std::mutex> MFilterMutex;
78-
std::unique_ptr<std::vector<plugin>> MPlugins;
79-
std::unique_ptr<device_filter_list> MDeviceFilterList;
74+
template <typename T, typename... Types>
75+
T &getOrCreate(InstWithLock<T> &IWL, Types... Args);
76+
77+
InstWithLock<Scheduler> MScheduler;
78+
InstWithLock<ProgramManager> MProgramManager;
79+
InstWithLock<Sync> MSync;
80+
InstWithLock<std::vector<PlatformImplPtr>> MPlatformCache;
81+
InstWithLock<std::mutex> MPlatformMapMutex;
82+
InstWithLock<std::mutex> MFilterMutex;
83+
InstWithLock<std::vector<plugin>> MPlugins;
84+
InstWithLock<device_filter_list> MDeviceFilterList;
8085
// The mutex for synchronizing accesses to handlers extended members
81-
std::unique_ptr<std::mutex> MHandlerExtendedMembersMutex;
86+
InstWithLock<std::mutex> MHandlerExtendedMembersMutex;
8287
};
8388
} // namespace detail
8489
} // namespace sycl

0 commit comments

Comments
 (0)