diff --git a/openmp/libomptarget/deviceRTLs/common/src/data_sharing.cu b/openmp/libomptarget/deviceRTLs/common/src/data_sharing.cu --- a/openmp/libomptarget/deviceRTLs/common/src/data_sharing.cu +++ b/openmp/libomptarget/deviceRTLs/common/src/data_sharing.cu @@ -36,6 +36,14 @@ } } +EXTERN void *__kmpc_alloc_shared(size_t DataSize) { + return (void *)SafeMalloc(DataSize, "Alloc Shared"); +} + +EXTERN void __kmpc_free_shared(void *FrameStart) { + SafeFree(FrameStart, "Free Shared"); +} + // Initialize data sharing data structure. This function needs to be called // once at the beginning of a data sharing context (coincides with the kernel // initialization). This function is called only by the MASTER thread of each @@ -207,24 +215,20 @@ } } -// Begin a data sharing context. Maintain a list of references to shared -// variables. This list of references to shared variables will be passed -// to one or more threads. -// In L0 data sharing this is called by master thread. -// In L1 data sharing this is called by active warp master thread. -EXTERN void __kmpc_begin_sharing_variables(void ***GlobalArgs, size_t nArgs) { - omptarget_nvptx_globalArgs.EnsureSize(nArgs); - *GlobalArgs = omptarget_nvptx_globalArgs.GetArgs(); +void** SHARED(GlobalArgs); +void* globalArgsStorage[64]; +#pragma omp allocate(globalArgsStorage) allocator(omp_pteam_mem_alloc) +EXTERN void __kmpc_begin_sharing_variables(void ***GlobalArgsPtr, size_t nArgs) { + if (nArgs > 64) { + *GlobalArgsPtr = GlobalArgs = reinterpret_cast(__kmpc_alloc_shared(nArgs * sizeof(void*))); + } else { + *GlobalArgsPtr = GlobalArgs = &globalArgsStorage[0]; + } } -// End a data sharing context. There is no need to have a list of refs -// to shared variables because the context in which those variables were -// shared has now ended. This should clean-up the list of references only -// without affecting the actual global storage of the variables. -// In L0 data sharing this is called by master thread. -// In L1 data sharing this is called by active warp master thread. EXTERN void __kmpc_end_sharing_variables() { - omptarget_nvptx_globalArgs.DeInit(); + if (GlobalArgs != &globalArgsStorage[0]) + __kmpc_free_shared(GlobalArgs); } // This function will return a list of references to global variables. This @@ -232,8 +236,9 @@ // members of this list will be passed to the outlined parallel function // preserving the order. // Called by all workers. -EXTERN void __kmpc_get_shared_variables(void ***GlobalArgs) { - *GlobalArgs = omptarget_nvptx_globalArgs.GetArgs(); + +EXTERN void __kmpc_get_shared_variables(void ***GlobalArgsPtr) { + *GlobalArgsPtr = GlobalArgs; } // This function is used to init static memory manager. This manager is used to diff --git a/openmp/libomptarget/deviceRTLs/interface.h b/openmp/libomptarget/deviceRTLs/interface.h --- a/openmp/libomptarget/deviceRTLs/interface.h +++ b/openmp/libomptarget/deviceRTLs/interface.h @@ -462,4 +462,14 @@ EXTERN void __kmpc_restore_team_static_memory(int16_t isSPMDExecutionMode, int16_t is_shared); +/// Allocate \p Bytes in "shareable" memory and return the address. Needs to be +/// called balanced with __kmpc_free_shared like a stack (push/pop). Can be +/// called by any thread, allocation happens per-thread. +EXTERN void *__kmpc_alloc_shared(uint64_t Bytes); + +/// Deallocate \p Ptr. Needs to be called balanced with __kmpc_alloc_shared like +/// a stack (push/pop). Can be called by any thread. \p Ptr must be allocated by +/// __kmpc_alloc_shared by the same thread. +EXTERN void __kmpc_free_shared(void *Ptr); + #endif