Skip to content

Commit 0c2897b

Browse files
authored
Lock USVM entry-points (#165)
* Lock USVM entry-points While testing AdaptiveCpp/AdaptiveCpp#1948 with the SYCL CTS I spotted regressions with the `marray` tests when using the usvm emulation layer ontop of Intel USM. From my investigations the AdaptiveCpp runtime threads to do asynchronous allocations frees, and the lack of thread safety in the layers entry-points causes issues with accessing the `std::map` objects. With this change the regressions disappear. I don't think there's an underlying spec issue here, as OpenCL entry-points are generally thread safe by default apart from those operating on `cl_kernel`, so I didn't add the lock to `clSetKernelArgSVMPointer` or clSetKernelExecInfo`. * Move mutex to context static member
1 parent ccefb07 commit 0c2897b

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

layers/99_svmplusplus/emulate.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <memory>
1313
#include <string>
1414
#include <vector>
15+
#include <mutex>
1516

1617
#include <cassert>
1718

@@ -330,6 +331,8 @@ struct SLayerContext
330331
EventMap.erase(event);
331332
}
332333

334+
// Locked on thread-safe CL entry-points
335+
static std::mutex Mutex;
333336
private:
334337
void getSVMTypesForPlatform(cl_platform_id platform)
335338
{
@@ -500,9 +503,10 @@ struct SLayerContext
500503
std::map<cl_context, CAllocMap> AllocMaps;
501504

502505
std::map<cl_event, SEventInfo> EventMap;
503-
504506
};
505507

508+
std::mutex SLayerContext::Mutex;
509+
506510
SLayerContext& getLayerContext(void)
507511
{
508512
static SLayerContext c;
@@ -654,6 +658,7 @@ void* CL_API_CALL clSVMAllocWithPropertiesKHR_EMU(
654658
size_t size,
655659
cl_int* errcode_ret)
656660
{
661+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
657662
cl_platform_id platform = getPlatform(context);
658663
const auto& USMFuncs = getLayerContext().getUSMFuncs(platform);
659664

@@ -792,6 +797,7 @@ cl_int CL_API_CALL clSVMFreeWithPropertiesKHR_EMU(
792797
cl_svm_free_flags_khr flags,
793798
void* ptr)
794799
{
800+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
795801
if (ptr == nullptr) {
796802
return CL_SUCCESS;
797803
}
@@ -825,6 +831,7 @@ cl_int CL_API_CALL clGetSVMSuggestedTypeIndexKHR_EMU(
825831
size_t size,
826832
cl_uint* suggested_svm_type_index)
827833
{
834+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
828835
if (suggested_svm_type_index == nullptr) {
829836
return CL_INVALID_VALUE;
830837
}
@@ -888,6 +895,7 @@ cl_int CL_API_CALL clGetSVMPointerInfoKHR_EMU(
888895
void* param_value,
889896
size_t* param_value_size_ret)
890897
{
898+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
891899
const void* base = nullptr;
892900
SAllocInfo allocInfo;
893901
getLayerContext().findAllocInfo(context, ptr, base, allocInfo);
@@ -961,6 +969,7 @@ cl_int CL_API_CALL clGetDeviceInfo_override(
961969
void* param_value,
962970
size_t* param_value_size_ret)
963971
{
972+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
964973
switch(param_name) {
965974
case CL_DEVICE_EXTENSIONS:
966975
{
@@ -1090,6 +1099,7 @@ cl_int CL_API_CALL clGetEventInfo_override(
10901099
void* param_value,
10911100
size_t* param_value_size_ret)
10921101
{
1102+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
10931103
switch(param_name) {
10941104
case CL_EVENT_COMMAND_TYPE:
10951105
{
@@ -1122,6 +1132,7 @@ cl_int CL_API_CALL clGetPlatformInfo_override(
11221132
void* param_value,
11231133
size_t* param_value_size_ret)
11241134
{
1135+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
11251136
switch(param_name) {
11261137
case CL_PLATFORM_EXTENSIONS:
11271138
{
@@ -1346,6 +1357,7 @@ void CL_API_CALL clSVMFree_override(
13461357
cl_context context,
13471358
void* ptr)
13481359
{
1360+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
13491361
if (isUSMPtr(context, ptr)) {
13501362
cl_platform_id platform = getPlatform(context);
13511363
const auto& USMFuncs = getLayerContext().getUSMFuncs(platform);
@@ -1369,6 +1381,7 @@ cl_int CL_API_CALL clEnqueueSVMFree_override(
13691381
const cl_event* event_wait_list,
13701382
cl_event* event)
13711383
{
1384+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
13721385
std::vector<void*> nonNullPtrs;
13731386
for (cl_uint i = 0; i < num_svm_pointers; ++i) {
13741387
if (svm_pointers[i] != nullptr) {
@@ -1397,6 +1410,7 @@ cl_int CL_API_CALL clEnqueueSVMMemcpy_override(
13971410
const cl_event* event_wait_list,
13981411
cl_event* event)
13991412
{
1413+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
14001414
cl_context context = getContext(command_queue);
14011415

14021416
if (size == 0) {
@@ -1455,6 +1469,7 @@ cl_int CL_API_CALL clEnqueueSVMMemFill_override(
14551469
const cl_event* event_wait_list,
14561470
cl_event* event)
14571471
{
1472+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
14581473
cl_context context = getContext(command_queue);
14591474

14601475
if (size == 0) {
@@ -1513,6 +1528,7 @@ cl_int CL_API_CALL clEnqueueSVMMigrateMem_override(
15131528
const cl_event* event_wait_list,
15141529
cl_event* event)
15151530
{
1531+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
15161532
// for now, just emit a marker
15171533
cl_int ret = g_pNextDispatch->clEnqueueMarkerWithWaitList(
15181534
command_queue,
@@ -1529,6 +1545,7 @@ cl_int CL_API_CALL clEnqueueSVMMigrateMem_override(
15291545
cl_int CL_API_CALL clReleaseEvent_override(
15301546
cl_event event)
15311547
{
1548+
std::lock_guard<std::mutex> lock(SLayerContext::Mutex);
15321549
cl_uint refCount = 0;
15331550
g_pNextDispatch->clGetEventInfo(
15341551
event,

0 commit comments

Comments
 (0)