diff options
| author | 2017-01-14 19:55:43 +0000 | |
|---|---|---|
| committer | 2017-01-14 19:55:43 +0000 | |
| commit | bd3306aecb3a15e8967143b8cdbbccf2b1b19b74 (patch) | |
| tree | 309a8132b44564b9e634c0da6815187ce8eab27c /gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp | |
| parent | killp -a should not kill the window if only one pane. (diff) | |
| download | wireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.tar.xz wireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.zip | |
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp')
| -rw-r--r-- | gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp | 247 |
1 files changed, 154 insertions, 93 deletions
diff --git a/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp b/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp index 8215144a514..7d55641e4ce 100644 --- a/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp +++ b/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp @@ -17,131 +17,192 @@ using namespace llvm; using namespace llvm::orc; using namespace llvm::orc::remote; -class QueueChannel : public RPCChannel { +class Queue : public std::queue<char> { public: - QueueChannel(std::queue<char> &Queue) : Queue(Queue) {} + std::mutex &getLock() { return Lock; } + +private: + std::mutex Lock; +}; - std::error_code readBytes(char *Dst, unsigned Size) override { - while (Size--) { - *Dst++ = Queue.front(); - Queue.pop(); +class QueueChannel : public RPCChannel { +public: + QueueChannel(Queue &InQueue, Queue &OutQueue) + : InQueue(InQueue), OutQueue(OutQueue) {} + + Error readBytes(char *Dst, unsigned Size) override { + while (Size != 0) { + // If there's nothing to read then yield. + while (InQueue.empty()) + std::this_thread::yield(); + + // Lock the channel and read what we can. + std::lock_guard<std::mutex> Lock(InQueue.getLock()); + while (!InQueue.empty() && Size) { + *Dst++ = InQueue.front(); + --Size; + InQueue.pop(); + } } - return std::error_code(); + return Error::success(); } - std::error_code appendBytes(const char *Src, unsigned Size) override { + Error appendBytes(const char *Src, unsigned Size) override { + std::lock_guard<std::mutex> Lock(OutQueue.getLock()); while (Size--) - Queue.push(*Src++); - return std::error_code(); + OutQueue.push(*Src++); + return Error::success(); } - std::error_code send() override { return std::error_code(); } + Error send() override { return Error::success(); } private: - std::queue<char> &Queue; + Queue &InQueue; + Queue &OutQueue; }; -class DummyRPC : public testing::Test, - public RPC<QueueChannel> { +class DummyRPC : public testing::Test, public RPC<QueueChannel> { public: - typedef Procedure<1, bool> Proc1; - typedef Procedure<2, int8_t, - uint8_t, - int16_t, - uint16_t, - int32_t, - uint32_t, - int64_t, - uint64_t, - bool, - std::string, - std::vector<int>> AllTheTypes; + enum FuncId : uint32_t { + VoidBoolId = RPCFunctionIdTraits<FuncId>::FirstValidId, + IntIntId, + AllTheTypesId + }; + + typedef Function<VoidBoolId, void(bool)> VoidBool; + typedef Function<IntIntId, int32_t(int32_t)> IntInt; + typedef Function<AllTheTypesId, + void(int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, + int64_t, uint64_t, bool, std::string, std::vector<int>)> + AllTheTypes; }; +TEST_F(DummyRPC, TestAsyncVoidBool) { + Queue Q1, Q2; + QueueChannel C1(Q1, Q2); + QueueChannel C2(Q2, Q1); + + // Make an async call. + auto ResOrErr = callAsyncWithSeq<VoidBool>(C1, true); + EXPECT_TRUE(!!ResOrErr) << "Simple call over queue failed"; -TEST_F(DummyRPC, TestBasic) { - std::queue<char> Queue; - QueueChannel C(Queue); + { + // Expect a call to Proc1. + auto EC = expect<VoidBool>(C2, [&](bool &B) { + EXPECT_EQ(B, true) << "Bool serialization broken"; + return Error::success(); + }); + EXPECT_FALSE(EC) << "Simple expect over queue failed"; + } { - // Make a call to Proc1. - auto EC = call<Proc1>(C, true); - EXPECT_FALSE(EC) << "Simple call over queue failed"; + // Wait for the result. + auto EC = waitForResult(C1, ResOrErr->second, handleNone); + EXPECT_FALSE(EC) << "Could not read result."; } + // Verify that the function returned ok. + auto Val = ResOrErr->first.get(); + EXPECT_TRUE(Val) << "Remote void function failed to execute."; +} + +TEST_F(DummyRPC, TestAsyncIntInt) { + Queue Q1, Q2; + QueueChannel C1(Q1, Q2); + QueueChannel C2(Q2, Q1); + + // Make an async call. + auto ResOrErr = callAsyncWithSeq<IntInt>(C1, 21); + EXPECT_TRUE(!!ResOrErr) << "Simple call over queue failed"; + { // Expect a call to Proc1. - auto EC = expect<Proc1>(C, - [&](bool &B) { - EXPECT_EQ(B, true) - << "Bool serialization broken"; - return std::error_code(); - }); + auto EC = expect<IntInt>(C2, [&](int32_t I) -> Expected<int32_t> { + EXPECT_EQ(I, 21) << "Bool serialization broken"; + return 2 * I; + }); EXPECT_FALSE(EC) << "Simple expect over queue failed"; } + + { + // Wait for the result. + auto EC = waitForResult(C1, ResOrErr->second, handleNone); + EXPECT_FALSE(EC) << "Could not read result."; + } + + // Verify that the function returned ok. + auto Val = ResOrErr->first.get(); + EXPECT_TRUE(!!Val) << "Remote int function failed to execute."; + EXPECT_EQ(*Val, 42) << "Remote int function return wrong value."; } TEST_F(DummyRPC, TestSerialization) { - std::queue<char> Queue; - QueueChannel C(Queue); + Queue Q1, Q2; + QueueChannel C1(Q1, Q2); + QueueChannel C2(Q2, Q1); + + // Make a call to Proc1. + std::vector<int> v({42, 7}); + auto ResOrErr = callAsyncWithSeq<AllTheTypes>( + C1, -101, 250, -10000, 10000, -1000000000, 1000000000, -10000000000, + 10000000000, true, "foo", v); + EXPECT_TRUE(!!ResOrErr) << "Big (serialization test) call over queue failed"; { - // Make a call to Proc1. - std::vector<int> v({42, 7}); - auto EC = call<AllTheTypes>(C, - -101, - 250, - -10000, - 10000, - -1000000000, - 1000000000, - -10000000000, - 10000000000, - true, - "foo", - v); + // Expect a call to Proc1. + auto EC = expect<AllTheTypes>( + C2, [&](int8_t &s8, uint8_t &u8, int16_t &s16, uint16_t &u16, + int32_t &s32, uint32_t &u32, int64_t &s64, uint64_t &u64, + bool &b, std::string &s, std::vector<int> &v) { + + EXPECT_EQ(s8, -101) << "int8_t serialization broken"; + EXPECT_EQ(u8, 250) << "uint8_t serialization broken"; + EXPECT_EQ(s16, -10000) << "int16_t serialization broken"; + EXPECT_EQ(u16, 10000) << "uint16_t serialization broken"; + EXPECT_EQ(s32, -1000000000) << "int32_t serialization broken"; + EXPECT_EQ(u32, 1000000000ULL) << "uint32_t serialization broken"; + EXPECT_EQ(s64, -10000000000) << "int64_t serialization broken"; + EXPECT_EQ(u64, 10000000000ULL) << "uint64_t serialization broken"; + EXPECT_EQ(b, true) << "bool serialization broken"; + EXPECT_EQ(s, "foo") << "std::string serialization broken"; + EXPECT_EQ(v, std::vector<int>({42, 7})) + << "std::vector serialization broken"; + return Error::success(); + }); EXPECT_FALSE(EC) << "Big (serialization test) call over queue failed"; } { - // Expect a call to Proc1. - auto EC = expect<AllTheTypes>(C, - [&](int8_t &s8, - uint8_t &u8, - int16_t &s16, - uint16_t &u16, - int32_t &s32, - uint32_t &u32, - int64_t &s64, - uint64_t &u64, - bool &b, - std::string &s, - std::vector<int> &v) { - - EXPECT_EQ(s8, -101) - << "int8_t serialization broken"; - EXPECT_EQ(u8, 250) - << "uint8_t serialization broken"; - EXPECT_EQ(s16, -10000) - << "int16_t serialization broken"; - EXPECT_EQ(u16, 10000) - << "uint16_t serialization broken"; - EXPECT_EQ(s32, -1000000000) - << "int32_t serialization broken"; - EXPECT_EQ(u32, 1000000000ULL) - << "uint32_t serialization broken"; - EXPECT_EQ(s64, -10000000000) - << "int64_t serialization broken"; - EXPECT_EQ(u64, 10000000000ULL) - << "uint64_t serialization broken"; - EXPECT_EQ(b, true) - << "bool serialization broken"; - EXPECT_EQ(s, "foo") - << "std::string serialization broken"; - EXPECT_EQ(v, std::vector<int>({42, 7})) - << "std::vector serialization broken"; - return std::error_code(); - }); - EXPECT_FALSE(EC) << "Big (serialization test) call over queue failed"; + // Wait for the result. + auto EC = waitForResult(C1, ResOrErr->second, handleNone); + EXPECT_FALSE(EC) << "Could not read result."; } + + // Verify that the function returned ok. + auto Val = ResOrErr->first.get(); + EXPECT_TRUE(Val) << "Remote void function failed to execute."; } + +// Test the synchronous call API. +// FIXME: Re-enable once deadlock encountered on S390 has been debugged / fixed, +// see http://lab.llvm.org:8011/builders/clang-s390x-linux/builds/3459 +// TEST_F(DummyRPC, TestSynchronousCall) { +// Queue Q1, Q2; +// QueueChannel C1(Q1, Q2); +// QueueChannel C2(Q2, Q1); +// +// auto ServerResult = +// std::async(std::launch::async, +// [&]() { +// return expect<IntInt>(C2, [&](int32_t V) { return V; }); +// }); +// +// auto ValOrErr = callST<IntInt>(C1, 42); +// +// EXPECT_FALSE(!!ServerResult.get()) +// << "Server returned an error."; +// EXPECT_TRUE(!!ValOrErr) +// << "callST returned an error."; +// EXPECT_EQ(*ValOrErr, 42) +// << "Incorrect callST<IntInt> result"; +// } |
