xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp (revision bcdfcbcb1d8694c0f0630e3c326cbda437b24c14)
1 //===--- ThreadSafeModuleTest.cpp - Test basic use of ThreadSafeModule ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
11 #include "gtest/gtest.h"
12 
13 #include <atomic>
14 #include <future>
15 #include <thread>
16 
17 using namespace llvm;
18 using namespace llvm::orc;
19 
20 namespace {
21 
22 TEST(ThreadSafeModuleTest, ContextWhollyOwnedByOneModule) {
23   // Test that ownership of a context can be transferred to a single
24   // ThreadSafeModule.
25   ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
26   ThreadSafeModule TSM(llvm::make_unique<Module>("M", *TSCtx.getContext()),
27                        std::move(TSCtx));
28 }
29 
30 TEST(ThreadSafeModuleTest, ContextOwnershipSharedByTwoModules) {
31   // Test that ownership of a context can be shared between more than one
32   // ThreadSafeModule.
33   ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
34 
35   ThreadSafeModule TSM1(llvm::make_unique<Module>("M1", *TSCtx.getContext()),
36                         TSCtx);
37   ThreadSafeModule TSM2(llvm::make_unique<Module>("M2", *TSCtx.getContext()),
38                         std::move(TSCtx));
39 }
40 
41 TEST(ThreadSafeModuleTest, ContextOwnershipSharedWithClient) {
42   // Test that ownership of a context can be shared with a client-held
43   // ThreadSafeContext so that it can be re-used for new modules.
44   ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
45 
46   {
47     // Create and destroy a module.
48     ThreadSafeModule TSM1(llvm::make_unique<Module>("M1", *TSCtx.getContext()),
49                           TSCtx);
50   }
51 
52   // Verify that the context is still available for re-use.
53   ThreadSafeModule TSM2(llvm::make_unique<Module>("M2", *TSCtx.getContext()),
54                         std::move(TSCtx));
55 }
56 
57 TEST(ThreadSafeModuleTest, BasicContextLockAPI) {
58   // Test that basic lock API calls work.
59   ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
60   ThreadSafeModule TSM(llvm::make_unique<Module>("M", *TSCtx.getContext()),
61                        TSCtx);
62 
63   { auto L = TSCtx.getLock(); }
64 
65   { auto L = TSM.getContextLock(); }
66 }
67 
68 TEST(ThreadSafeModuleTest, ContextLockPreservesContext) {
69   // Test that the existence of a context lock preserves the attached
70   // context.
71   // The trick to verify this is a bit of a hack: We attach a Module
72   // (without the ThreadSafeModule wrapper) to the context, then verify
73   // that this Module destructs safely (which it will not if its context
74   // has been destroyed) even though all references to the context have
75   // been thrown away (apart from the lock).
76 
77   ThreadSafeContext TSCtx(llvm::make_unique<LLVMContext>());
78   auto L = TSCtx.getLock();
79   auto &Ctx = *TSCtx.getContext();
80   auto M = llvm::make_unique<Module>("M", Ctx);
81   TSCtx = ThreadSafeContext();
82 }
83 
84 } // end anonymous namespace
85