brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 7775f3c Raw
139 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "OrcTestCommon.h"10#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX11#include "llvm/ExecutionEngine/JITLink/JITLink.h"12#include "llvm/ExecutionEngine/Orc/MemoryMapper.h"13#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"14#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"15#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"16#include "llvm/Testing/Support/Error.h"17 18using namespace llvm;19using namespace llvm::orc;20using namespace llvm::orc::shared;21using namespace llvm::orc::rt_bootstrap;22 23#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)24 25// A basic function to be used as both initializer/deinitializer26CWrapperFunctionResult incrementWrapper(const char *ArgData, size_t ArgSize) {27  return WrapperFunction<SPSError(SPSExecutorAddr)>::handle(28             ArgData, ArgSize,29             [](ExecutorAddr A) -> Error {30               *A.toPtr<int *>() += 1;31               return Error::success();32             })33      .release();34}35 36TEST(SharedMemoryMapperTest, MemReserveInitializeDeinitializeRelease) {37  // These counters are used to track how many times the initializer and38  // deinitializer functions are called39  int InitializeCounter = 0;40  int DeinitializeCounter = 0;41 42  auto SelfEPC = cantFail(SelfExecutorProcessControl::Create());43 44  ExecutorSharedMemoryMapperService MapperService;45 46  SharedMemoryMapper::SymbolAddrs SAs;47  {48    StringMap<ExecutorAddr> Map;49    MapperService.addBootstrapSymbols(Map);50    SAs.Instance = Map[rt::ExecutorSharedMemoryMapperServiceInstanceName];51    SAs.Reserve = Map[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName];52    SAs.Initialize =53        Map[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName];54    SAs.Deinitialize =55        Map[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName];56    SAs.Release = Map[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName];57  }58 59  std::string TestString = "Hello, World!";60 61  // barrier62  std::promise<void> P;63  auto F = P.get_future();64 65  {66    std::unique_ptr<MemoryMapper> Mapper =67        cantFail(SharedMemoryMapper::Create(*SelfEPC, SAs));68 69    auto PageSize = Mapper->getPageSize();70    size_t ReqSize = PageSize;71    jitlink::LinkGraph G("G", std::make_shared<SymbolStringPool>(),72                         Triple("x86_64-apple-darwin"), SubtargetFeatures(),73                         jitlink::getGenericEdgeKindName);74 75    Mapper->reserve(ReqSize, [&](Expected<ExecutorAddrRange> Result) {76      EXPECT_THAT_ERROR(Result.takeError(), Succeeded());77      auto Reservation = std::move(*Result);78      {79        char *Addr =80            Mapper->prepare(G, Reservation.Start, TestString.size() + 1);81        std::strcpy(Addr, TestString.c_str());82      }83      MemoryMapper::AllocInfo AI;84      {85        MemoryMapper::AllocInfo::SegInfo SI;86        SI.Offset = 0;87        SI.ContentSize = TestString.size() + 1;88        SI.ZeroFillSize = PageSize - SI.ContentSize;89        SI.AG = MemProt::Read | MemProt::Write;90 91        AI.MappingBase = Reservation.Start;92        AI.Segments.push_back(SI);93        AI.Actions.push_back(94            {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(95                 ExecutorAddr::fromPtr(incrementWrapper),96                 ExecutorAddr::fromPtr(&InitializeCounter))),97             cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(98                 ExecutorAddr::fromPtr(incrementWrapper),99                 ExecutorAddr::fromPtr(&DeinitializeCounter)))});100      }101 102      EXPECT_EQ(InitializeCounter, 0);103      EXPECT_EQ(DeinitializeCounter, 0);104 105      Mapper->initialize(AI, [&, Reservation](Expected<ExecutorAddr> Result) {106        EXPECT_THAT_ERROR(Result.takeError(), Succeeded());107 108        EXPECT_EQ(TestString, std::string(static_cast<char *>(109                                  Reservation.Start.toPtr<char *>())));110 111        EXPECT_EQ(InitializeCounter, 1);112        EXPECT_EQ(DeinitializeCounter, 0);113 114        Mapper->deinitialize({*Result}, [&, Reservation](Error Err) {115          EXPECT_THAT_ERROR(std::move(Err), Succeeded());116 117          EXPECT_EQ(InitializeCounter, 1);118          EXPECT_EQ(DeinitializeCounter, 1);119 120          Mapper->release({Reservation.Start}, [&](Error Err) {121            EXPECT_THAT_ERROR(std::move(Err), Succeeded());122 123            P.set_value();124          });125        });126      });127    });128 129    // This will block the test if any of the above callbacks are not executed130    F.wait();131    // Mapper must be destructed before calling shutdown to avoid double free132  }133 134  EXPECT_THAT_ERROR(MapperService.shutdown(), Succeeded());135  cantFail(SelfEPC->disconnect());136}137 138#endif139