1 //===- SharedMemoryMapperTest.cpp -- Tests for SharedMemoryMapper ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "OrcTestCommon.h" 10 11 #include "llvm/ExecutionEngine/Orc/MemoryMapper.h" 12 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" 13 #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h" 14 #include "llvm/Testing/Support/Error.h" 15 16 using namespace llvm; 17 using namespace llvm::orc; 18 using namespace llvm::orc::shared; 19 using namespace llvm::orc::rt_bootstrap; 20 21 // A basic function to be used as both initializer/deinitializer 22 orc::shared::CWrapperFunctionResult incrementWrapper(const char *ArgData, 23 size_t ArgSize) { 24 return WrapperFunction<SPSError(SPSExecutorAddr)>::handle( 25 ArgData, ArgSize, 26 [](ExecutorAddr A) -> Error { 27 *A.toPtr<int *>() += 1; 28 return Error::success(); 29 }) 30 .release(); 31 } 32 33 TEST(SharedMemoryMapperTest, MemReserveInitializeDeinitializeRelease) { 34 // These counters are used to track how many times the initializer and 35 // deinitializer functions are called 36 int InitializeCounter = 0; 37 int DeinitializeCounter = 0; 38 39 auto SelfEPC = cantFail(SelfExecutorProcessControl::Create()); 40 41 ExecutorSharedMemoryMapperService MapperService; 42 43 SharedMemoryMapper::SymbolAddrs SAs; 44 { 45 StringMap<ExecutorAddr> Map; 46 MapperService.addBootstrapSymbols(Map); 47 SAs.Instance = Map[rt::ExecutorSharedMemoryMapperServiceInstanceName]; 48 SAs.Reserve = Map[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName]; 49 SAs.Initialize = 50 Map[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName]; 51 SAs.Deinitialize = 52 Map[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName]; 53 SAs.Release = Map[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName]; 54 } 55 56 std::string TestString = "Hello, World!"; 57 58 // barrier 59 std::promise<void> P; 60 auto F = P.get_future(); 61 62 { 63 auto PageSize = cantFail(sys::Process::getPageSize()); 64 size_t ReqSize = PageSize; 65 66 std::unique_ptr<MemoryMapper> Mapper = 67 std::make_unique<SharedMemoryMapper>(*SelfEPC, SAs); 68 69 Mapper->reserve(ReqSize, [&](Expected<ExecutorAddrRange> Result) { 70 EXPECT_THAT_ERROR(Result.takeError(), Succeeded()); 71 auto Reservation = std::move(*Result); 72 { 73 char *Addr = Mapper->prepare(Reservation.Start, TestString.size() + 1); 74 std::strcpy(Addr, TestString.c_str()); 75 } 76 MemoryMapper::AllocInfo AI; 77 { 78 MemoryMapper::AllocInfo::SegInfo SI; 79 SI.Offset = 0; 80 SI.ContentSize = TestString.size() + 1; 81 SI.ZeroFillSize = PageSize - SI.ContentSize; 82 SI.Prot = sys::Memory::MF_READ | sys::Memory::MF_WRITE; 83 84 AI.MappingBase = Reservation.Start; 85 AI.Segments.push_back(SI); 86 AI.Actions.push_back( 87 {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>( 88 ExecutorAddr::fromPtr(incrementWrapper), 89 ExecutorAddr::fromPtr(&InitializeCounter))), 90 cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>( 91 ExecutorAddr::fromPtr(incrementWrapper), 92 ExecutorAddr::fromPtr(&DeinitializeCounter)))}); 93 } 94 95 EXPECT_EQ(InitializeCounter, 0); 96 EXPECT_EQ(DeinitializeCounter, 0); 97 98 Mapper->initialize(AI, [&, Reservation](Expected<ExecutorAddr> Result) { 99 EXPECT_THAT_ERROR(Result.takeError(), Succeeded()); 100 101 EXPECT_EQ(TestString, std::string(static_cast<char *>( 102 Reservation.Start.toPtr<char *>()))); 103 104 EXPECT_EQ(InitializeCounter, 1); 105 EXPECT_EQ(DeinitializeCounter, 0); 106 107 Mapper->deinitialize({*Result}, [&, Reservation](Error Err) { 108 EXPECT_THAT_ERROR(std::move(Err), Succeeded()); 109 110 EXPECT_EQ(InitializeCounter, 1); 111 EXPECT_EQ(DeinitializeCounter, 1); 112 113 Mapper->release({Reservation.Start}, [&](Error Err) { 114 EXPECT_THAT_ERROR(std::move(Err), Succeeded()); 115 116 P.set_value(); 117 }); 118 }); 119 }); 120 }); 121 122 // This will block the test if any of the above callbacks are not executed 123 F.wait(); 124 // Mapper must be destructed before calling shutdown to avoid double free 125 } 126 127 EXPECT_THAT_ERROR(MapperService.shutdown(), Succeeded()); 128 cantFail(SelfEPC->disconnect()); 129 } 130