summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-01-14 19:55:43 +0000
committerpatrick <patrick@openbsd.org>2017-01-14 19:55:43 +0000
commitbd3306aecb3a15e8967143b8cdbbccf2b1b19b74 (patch)
tree309a8132b44564b9e634c0da6815187ce8eab27c /gnu/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
parentkillp -a should not kill the window if only one pane. (diff)
downloadwireguard-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.cpp247
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";
+// }