@@ -66,6 +66,18 @@ using ipcTestParams =
6666struct umfIpcTest : umf_test::test,
6767 ::testing::WithParamInterface<ipcTestParams> {
6868 umfIpcTest () {}
69+ size_t getOpenedIpcCacheSize () {
70+ const char *max_size_str = getenv (" UMF_MAX_OPENED_IPC_HANDLES" );
71+ if (max_size_str) {
72+ char *endptr;
73+ size_t max_size = strtoul (max_size_str, &endptr, 10 );
74+ EXPECT_EQ (*endptr, ' \0 ' );
75+ if (*endptr == ' \0 ' ) {
76+ return max_size;
77+ }
78+ }
79+ return 0 ;
80+ }
6981 void SetUp () override {
7082 test::SetUp ();
7183 auto [pool_ops, pool_params_create, pool_params_destroy, provider_ops,
@@ -78,6 +90,7 @@ struct umfIpcTest : umf_test::test,
7890 providerParamsCreate = provider_params_create;
7991 providerParamsDestroy = provider_params_destroy;
8092 memAccessor = accessor;
93+ openedIpcCacheSize = getOpenedIpcCacheSize ();
8194 }
8295
8396 void TearDown () override { test::TearDown (); }
@@ -158,6 +171,7 @@ struct umfIpcTest : umf_test::test,
158171 umf_memory_provider_ops_t *providerOps = nullptr ;
159172 pfnProviderParamsCreate providerParamsCreate = nullptr ;
160173 pfnProviderParamsDestroy providerParamsDestroy = nullptr ;
174+ size_t openedIpcCacheSize = 0 ;
161175};
162176
163177TEST_P (umfIpcTest, GetIPCHandleSize) {
@@ -458,7 +472,7 @@ TEST_P(umfIpcTest, ConcurrentGetPutHandles) {
458472 EXPECT_EQ (stat.putCount , stat.getCount );
459473}
460474
461- TEST_P (umfIpcTest, ConcurrentOpenCloseHandles ) {
475+ TEST_P (umfIpcTest, ConcurrentOpenConcurrentCloseHandles ) {
462476 umf_result_t ret;
463477 std::vector<void *> ptrs;
464478 constexpr size_t ALLOC_SIZE = 100 ;
@@ -529,6 +543,68 @@ TEST_P(umfIpcTest, ConcurrentOpenCloseHandles) {
529543 EXPECT_EQ (stat.openCount , stat.closeCount );
530544}
531545
546+ TEST_P (umfIpcTest, ConcurrentOpenCloseHandles) {
547+ umf_result_t ret;
548+ std::vector<void *> ptrs;
549+ constexpr size_t ALLOC_SIZE = 100 ;
550+ constexpr size_t NUM_POINTERS = 100 ;
551+ umf::pool_unique_handle_t pool = makePool ();
552+ ASSERT_NE (pool.get (), nullptr );
553+
554+ for (size_t i = 0 ; i < NUM_POINTERS; ++i) {
555+ void *ptr = umfPoolMalloc (pool.get (), ALLOC_SIZE);
556+ EXPECT_NE (ptr, nullptr );
557+ ptrs.push_back (ptr);
558+ }
559+
560+ std::array<umf_ipc_handle_t , NUM_POINTERS> ipcHandles;
561+ for (size_t i = 0 ; i < NUM_POINTERS; ++i) {
562+ umf_ipc_handle_t ipcHandle;
563+ size_t handleSize;
564+ ret = umfGetIPCHandle (ptrs[i], &ipcHandle, &handleSize);
565+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
566+ ipcHandles[i] = ipcHandle;
567+ }
568+
569+ umf_ipc_handler_handle_t ipcHandler = nullptr ;
570+ ret = umfPoolGetIPCHandler (pool.get (), &ipcHandler);
571+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
572+ ASSERT_NE (ipcHandler, nullptr );
573+
574+ umf_test::syncthreads_barrier syncthreads (NTHREADS);
575+
576+ auto openCloseHandlesFn = [&ipcHandles, &syncthreads, ipcHandler](size_t ) {
577+ syncthreads ();
578+ for (auto ipcHandle : ipcHandles) {
579+ void *ptr;
580+ umf_result_t ret = umfOpenIPCHandle (ipcHandler, ipcHandle, &ptr);
581+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
582+ ret = umfCloseIPCHandle (ptr);
583+ EXPECT_EQ (ret, UMF_RESULT_SUCCESS);
584+ }
585+ };
586+
587+ umf_test::parallel_exec (NTHREADS, openCloseHandlesFn);
588+
589+ for (auto ipcHandle : ipcHandles) {
590+ ret = umfPutIPCHandle (ipcHandle);
591+ EXPECT_EQ (ret, UMF_RESULT_SUCCESS);
592+ }
593+
594+ for (void *ptr : ptrs) {
595+ ret = umfPoolFree (pool.get (), ptr);
596+ EXPECT_EQ (ret, UMF_RESULT_SUCCESS);
597+ }
598+
599+ pool.reset (nullptr );
600+ EXPECT_EQ (stat.getCount , stat.allocCount );
601+ EXPECT_EQ (stat.putCount , stat.getCount );
602+ if (openedIpcCacheSize == 0 ) {
603+ EXPECT_EQ (stat.openCount , stat.allocCount );
604+ }
605+ EXPECT_EQ (stat.openCount , stat.closeCount );
606+ }
607+
532608TEST_P (umfIpcTest, ConcurrentDestroyIpcHandlers) {
533609 constexpr size_t SIZE = 100 ;
534610 constexpr size_t NUM_ALLOCS = 100 ;
0 commit comments