xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/SharedMemoryMapperTest.cpp (revision 89e6a288674c9fae33aeb5448c7b1fe782b2bf53)
11b1f1c77SAnubhab Ghosh //===- SharedMemoryMapperTest.cpp -- Tests for SharedMemoryMapper ---------===//
21b1f1c77SAnubhab Ghosh //
31b1f1c77SAnubhab Ghosh // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41b1f1c77SAnubhab Ghosh // See https://llvm.org/LICENSE.txt for license information.
51b1f1c77SAnubhab Ghosh // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61b1f1c77SAnubhab Ghosh //
71b1f1c77SAnubhab Ghosh //===----------------------------------------------------------------------===//
81b1f1c77SAnubhab Ghosh 
91b1f1c77SAnubhab Ghosh #include "OrcTestCommon.h"
10*89e6a288SDaniil Fukalov #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
111b1f1c77SAnubhab Ghosh #include "llvm/ExecutionEngine/Orc/MemoryMapper.h"
121b1f1c77SAnubhab Ghosh #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
131b1f1c77SAnubhab Ghosh #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"
141b1f1c77SAnubhab Ghosh #include "llvm/Testing/Support/Error.h"
151b1f1c77SAnubhab Ghosh 
161b1f1c77SAnubhab Ghosh using namespace llvm;
171b1f1c77SAnubhab Ghosh using namespace llvm::orc;
181b1f1c77SAnubhab Ghosh using namespace llvm::orc::shared;
191b1f1c77SAnubhab Ghosh using namespace llvm::orc::rt_bootstrap;
201b1f1c77SAnubhab Ghosh 
21ac3cb4ecSAnubhab Ghosh #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
221b1f1c77SAnubhab Ghosh 
231b1f1c77SAnubhab Ghosh // A basic function to be used as both initializer/deinitializer
241b1f1c77SAnubhab Ghosh orc::shared::CWrapperFunctionResult incrementWrapper(const char *ArgData,
251b1f1c77SAnubhab Ghosh                                                      size_t ArgSize) {
261b1f1c77SAnubhab Ghosh   return WrapperFunction<SPSError(SPSExecutorAddr)>::handle(
271b1f1c77SAnubhab Ghosh              ArgData, ArgSize,
281b1f1c77SAnubhab Ghosh              [](ExecutorAddr A) -> Error {
291b1f1c77SAnubhab Ghosh                *A.toPtr<int *>() += 1;
301b1f1c77SAnubhab Ghosh                return Error::success();
311b1f1c77SAnubhab Ghosh              })
321b1f1c77SAnubhab Ghosh       .release();
331b1f1c77SAnubhab Ghosh }
341b1f1c77SAnubhab Ghosh 
351b1f1c77SAnubhab Ghosh TEST(SharedMemoryMapperTest, MemReserveInitializeDeinitializeRelease) {
361b1f1c77SAnubhab Ghosh   // These counters are used to track how many times the initializer and
371b1f1c77SAnubhab Ghosh   // deinitializer functions are called
381b1f1c77SAnubhab Ghosh   int InitializeCounter = 0;
391b1f1c77SAnubhab Ghosh   int DeinitializeCounter = 0;
401b1f1c77SAnubhab Ghosh 
411b1f1c77SAnubhab Ghosh   auto SelfEPC = cantFail(SelfExecutorProcessControl::Create());
421b1f1c77SAnubhab Ghosh 
431b1f1c77SAnubhab Ghosh   ExecutorSharedMemoryMapperService MapperService;
441b1f1c77SAnubhab Ghosh 
451b1f1c77SAnubhab Ghosh   SharedMemoryMapper::SymbolAddrs SAs;
461b1f1c77SAnubhab Ghosh   {
471b1f1c77SAnubhab Ghosh     StringMap<ExecutorAddr> Map;
481b1f1c77SAnubhab Ghosh     MapperService.addBootstrapSymbols(Map);
491b1f1c77SAnubhab Ghosh     SAs.Instance = Map[rt::ExecutorSharedMemoryMapperServiceInstanceName];
501b1f1c77SAnubhab Ghosh     SAs.Reserve = Map[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName];
511b1f1c77SAnubhab Ghosh     SAs.Initialize =
521b1f1c77SAnubhab Ghosh         Map[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName];
531b1f1c77SAnubhab Ghosh     SAs.Deinitialize =
541b1f1c77SAnubhab Ghosh         Map[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName];
551b1f1c77SAnubhab Ghosh     SAs.Release = Map[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName];
561b1f1c77SAnubhab Ghosh   }
571b1f1c77SAnubhab Ghosh 
581b1f1c77SAnubhab Ghosh   std::string TestString = "Hello, World!";
591b1f1c77SAnubhab Ghosh 
601b1f1c77SAnubhab Ghosh   // barrier
611b1f1c77SAnubhab Ghosh   std::promise<void> P;
621b1f1c77SAnubhab Ghosh   auto F = P.get_future();
631b1f1c77SAnubhab Ghosh 
641b1f1c77SAnubhab Ghosh   {
651b1f1c77SAnubhab Ghosh     std::unique_ptr<MemoryMapper> Mapper =
664fcf8434SAnubhab Ghosh         cantFail(SharedMemoryMapper::Create(*SelfEPC, SAs));
674fcf8434SAnubhab Ghosh 
684fcf8434SAnubhab Ghosh     auto PageSize = Mapper->getPageSize();
694fcf8434SAnubhab Ghosh     size_t ReqSize = PageSize;
701b1f1c77SAnubhab Ghosh 
711b1f1c77SAnubhab Ghosh     Mapper->reserve(ReqSize, [&](Expected<ExecutorAddrRange> Result) {
721b1f1c77SAnubhab Ghosh       EXPECT_THAT_ERROR(Result.takeError(), Succeeded());
731b1f1c77SAnubhab Ghosh       auto Reservation = std::move(*Result);
741b1f1c77SAnubhab Ghosh       {
751b1f1c77SAnubhab Ghosh         char *Addr = Mapper->prepare(Reservation.Start, TestString.size() + 1);
761b1f1c77SAnubhab Ghosh         std::strcpy(Addr, TestString.c_str());
771b1f1c77SAnubhab Ghosh       }
781b1f1c77SAnubhab Ghosh       MemoryMapper::AllocInfo AI;
791b1f1c77SAnubhab Ghosh       {
801b1f1c77SAnubhab Ghosh         MemoryMapper::AllocInfo::SegInfo SI;
811b1f1c77SAnubhab Ghosh         SI.Offset = 0;
821b1f1c77SAnubhab Ghosh         SI.ContentSize = TestString.size() + 1;
831b1f1c77SAnubhab Ghosh         SI.ZeroFillSize = PageSize - SI.ContentSize;
84d3d9f7caSLang Hames         SI.AG = MemProt::Read | MemProt::Write;
851b1f1c77SAnubhab Ghosh 
861b1f1c77SAnubhab Ghosh         AI.MappingBase = Reservation.Start;
871b1f1c77SAnubhab Ghosh         AI.Segments.push_back(SI);
881b1f1c77SAnubhab Ghosh         AI.Actions.push_back(
891b1f1c77SAnubhab Ghosh             {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
901b1f1c77SAnubhab Ghosh                  ExecutorAddr::fromPtr(incrementWrapper),
911b1f1c77SAnubhab Ghosh                  ExecutorAddr::fromPtr(&InitializeCounter))),
921b1f1c77SAnubhab Ghosh              cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
931b1f1c77SAnubhab Ghosh                  ExecutorAddr::fromPtr(incrementWrapper),
941b1f1c77SAnubhab Ghosh                  ExecutorAddr::fromPtr(&DeinitializeCounter)))});
951b1f1c77SAnubhab Ghosh       }
961b1f1c77SAnubhab Ghosh 
971b1f1c77SAnubhab Ghosh       EXPECT_EQ(InitializeCounter, 0);
981b1f1c77SAnubhab Ghosh       EXPECT_EQ(DeinitializeCounter, 0);
991b1f1c77SAnubhab Ghosh 
1001b1f1c77SAnubhab Ghosh       Mapper->initialize(AI, [&, Reservation](Expected<ExecutorAddr> Result) {
1011b1f1c77SAnubhab Ghosh         EXPECT_THAT_ERROR(Result.takeError(), Succeeded());
1021b1f1c77SAnubhab Ghosh 
1031b1f1c77SAnubhab Ghosh         EXPECT_EQ(TestString, std::string(static_cast<char *>(
1041b1f1c77SAnubhab Ghosh                                   Reservation.Start.toPtr<char *>())));
1051b1f1c77SAnubhab Ghosh 
1061b1f1c77SAnubhab Ghosh         EXPECT_EQ(InitializeCounter, 1);
1071b1f1c77SAnubhab Ghosh         EXPECT_EQ(DeinitializeCounter, 0);
1081b1f1c77SAnubhab Ghosh 
1091b1f1c77SAnubhab Ghosh         Mapper->deinitialize({*Result}, [&, Reservation](Error Err) {
1101b1f1c77SAnubhab Ghosh           EXPECT_THAT_ERROR(std::move(Err), Succeeded());
1111b1f1c77SAnubhab Ghosh 
1121b1f1c77SAnubhab Ghosh           EXPECT_EQ(InitializeCounter, 1);
1131b1f1c77SAnubhab Ghosh           EXPECT_EQ(DeinitializeCounter, 1);
1141b1f1c77SAnubhab Ghosh 
1151b1f1c77SAnubhab Ghosh           Mapper->release({Reservation.Start}, [&](Error Err) {
1161b1f1c77SAnubhab Ghosh             EXPECT_THAT_ERROR(std::move(Err), Succeeded());
1171b1f1c77SAnubhab Ghosh 
1181b1f1c77SAnubhab Ghosh             P.set_value();
1191b1f1c77SAnubhab Ghosh           });
1201b1f1c77SAnubhab Ghosh         });
1211b1f1c77SAnubhab Ghosh       });
1221b1f1c77SAnubhab Ghosh     });
1231b1f1c77SAnubhab Ghosh 
1241b1f1c77SAnubhab Ghosh     // This will block the test if any of the above callbacks are not executed
1251b1f1c77SAnubhab Ghosh     F.wait();
1261b1f1c77SAnubhab Ghosh     // Mapper must be destructed before calling shutdown to avoid double free
1271b1f1c77SAnubhab Ghosh   }
1281b1f1c77SAnubhab Ghosh 
1291b1f1c77SAnubhab Ghosh   EXPECT_THAT_ERROR(MapperService.shutdown(), Succeeded());
1301b1f1c77SAnubhab Ghosh   cantFail(SelfEPC->disconnect());
1311b1f1c77SAnubhab Ghosh }
1321b1f1c77SAnubhab Ghosh 
1331b1f1c77SAnubhab Ghosh #endif
134