1 //===- SharedMemoryMapperTest.cpp -- Tests for SharedMemoryMapper ---------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "OrcTestCommon.h"
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"
17 using namespace llvm::orc
;
18 using namespace llvm::orc::shared
;
19 using namespace llvm::orc::rt_bootstrap
;
21 #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
23 // A basic function to be used as both initializer/deinitializer
24 orc::shared::CWrapperFunctionResult
incrementWrapper(const char *ArgData
,
26 return WrapperFunction
<SPSError(SPSExecutorAddr
)>::handle(
28 [](ExecutorAddr A
) -> Error
{
29 *A
.toPtr
<int *>() += 1;
30 return Error::success();
35 TEST(SharedMemoryMapperTest
, MemReserveInitializeDeinitializeRelease
) {
36 // These counters are used to track how many times the initializer and
37 // deinitializer functions are called
38 int InitializeCounter
= 0;
39 int DeinitializeCounter
= 0;
41 auto SelfEPC
= cantFail(SelfExecutorProcessControl::Create());
43 ExecutorSharedMemoryMapperService MapperService
;
45 SharedMemoryMapper::SymbolAddrs SAs
;
47 StringMap
<ExecutorAddr
> Map
;
48 MapperService
.addBootstrapSymbols(Map
);
49 SAs
.Instance
= Map
[rt::ExecutorSharedMemoryMapperServiceInstanceName
];
50 SAs
.Reserve
= Map
[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName
];
52 Map
[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName
];
54 Map
[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName
];
55 SAs
.Release
= Map
[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName
];
58 std::string TestString
= "Hello, World!";
62 auto F
= P
.get_future();
65 std::unique_ptr
<MemoryMapper
> Mapper
=
66 cantFail(SharedMemoryMapper::Create(*SelfEPC
, SAs
));
68 auto PageSize
= Mapper
->getPageSize();
69 size_t ReqSize
= PageSize
;
71 Mapper
->reserve(ReqSize
, [&](Expected
<ExecutorAddrRange
> Result
) {
72 EXPECT_THAT_ERROR(Result
.takeError(), Succeeded());
73 auto Reservation
= std::move(*Result
);
75 char *Addr
= Mapper
->prepare(Reservation
.Start
, TestString
.size() + 1);
76 std::strcpy(Addr
, TestString
.c_str());
78 MemoryMapper::AllocInfo AI
;
80 MemoryMapper::AllocInfo::SegInfo SI
;
82 SI
.ContentSize
= TestString
.size() + 1;
83 SI
.ZeroFillSize
= PageSize
- SI
.ContentSize
;
84 SI
.AG
= MemProt::Read
| MemProt::Write
;
86 AI
.MappingBase
= Reservation
.Start
;
87 AI
.Segments
.push_back(SI
);
89 {cantFail(WrapperFunctionCall::Create
<SPSArgList
<SPSExecutorAddr
>>(
90 ExecutorAddr::fromPtr(incrementWrapper
),
91 ExecutorAddr::fromPtr(&InitializeCounter
))),
92 cantFail(WrapperFunctionCall::Create
<SPSArgList
<SPSExecutorAddr
>>(
93 ExecutorAddr::fromPtr(incrementWrapper
),
94 ExecutorAddr::fromPtr(&DeinitializeCounter
)))});
97 EXPECT_EQ(InitializeCounter
, 0);
98 EXPECT_EQ(DeinitializeCounter
, 0);
100 Mapper
->initialize(AI
, [&, Reservation
](Expected
<ExecutorAddr
> Result
) {
101 EXPECT_THAT_ERROR(Result
.takeError(), Succeeded());
103 EXPECT_EQ(TestString
, std::string(static_cast<char *>(
104 Reservation
.Start
.toPtr
<char *>())));
106 EXPECT_EQ(InitializeCounter
, 1);
107 EXPECT_EQ(DeinitializeCounter
, 0);
109 Mapper
->deinitialize({*Result
}, [&, Reservation
](Error Err
) {
110 EXPECT_THAT_ERROR(std::move(Err
), Succeeded());
112 EXPECT_EQ(InitializeCounter
, 1);
113 EXPECT_EQ(DeinitializeCounter
, 1);
115 Mapper
->release({Reservation
.Start
}, [&](Error Err
) {
116 EXPECT_THAT_ERROR(std::move(Err
), Succeeded());
124 // This will block the test if any of the above callbacks are not executed
126 // Mapper must be destructed before calling shutdown to avoid double free
129 EXPECT_THAT_ERROR(MapperService
.shutdown(), Succeeded());
130 cantFail(SelfEPC
->disconnect());