[llvm] r287121 - [Orc] Re-enable the RPC unit test disabled in r286917.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 16 09:31:10 PST 2016


Author: lhames
Date: Wed Nov 16 11:31:09 2016
New Revision: 287121

URL: http://llvm.org/viewvc/llvm-project?rev=287121&view=rev
Log:
[Orc] Re-enable the RPC unit test disabled in r286917.

This unit test infinite-looped on s390x due to a thread_yield being optimized
out. I've updated the QueueChannel class (where thread_yield was called) to use
a condition variable instead. This should cause the unit test to behave
correctly.


Modified:
    llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp?rev=287121&r1=287120&r2=287121&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp Wed Nov 16 11:31:09 2016
@@ -19,10 +19,11 @@ using namespace llvm::orc::rpc;
 
 class Queue : public std::queue<char> {
 public:
-  std::mutex &getLock() { return Lock; }
-
+  std::mutex &getMutex() { return M; }
+  std::condition_variable &getCondVar() { return CV; }
 private:
-  std::mutex Lock;
+  std::mutex M;
+  std::condition_variable CV;
 };
 
 class QueueChannel : public RawByteChannel {
@@ -31,26 +32,22 @@ public:
       : InQueue(InQueue), OutQueue(OutQueue) {}
 
   Error readBytes(char *Dst, unsigned Size) override {
-    while (Size != 0) {
-      // If there's nothing to read then yield.
+    std::unique_lock<std::mutex> Lock(InQueue.getMutex());
+    while (Size) {
       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();
-      }
+        InQueue.getCondVar().wait(Lock);
+      *Dst++ = InQueue.front();
+      --Size;
+      InQueue.pop();
     }
     return Error::success();
   }
 
   Error appendBytes(const char *Src, unsigned Size) override {
-    std::lock_guard<std::mutex> Lock(OutQueue.getLock());
+    std::unique_lock<std::mutex> Lock(OutQueue.getMutex());
     while (Size--)
       OutQueue.push(*Src++);
+    OutQueue.getCondVar().notify_one();
     return Error::success();
   }
 
@@ -93,162 +90,160 @@ private:
   QueueChannel C;
 };
 
-// FIXME: Temporarily disabled while the infnite loop discovered in r286639 is
-//        fixed (see llvm commits list discussion for that commit).
 
-// TEST(DummyRPC, TestAsyncVoidBool) {
-//   Queue Q1, Q2;
-//   DummyRPCEndpoint Client(Q1, Q2);
-//   DummyRPCEndpoint Server(Q2, Q1);
-
-//   std::thread ServerThread([&]() {
-//       Server.addHandler<DummyRPCAPI::VoidBool>(
-//           [](bool B) {
-//             EXPECT_EQ(B, true)
-//               << "Server void(bool) received unexpected result";
-//           });
-
-//       {
-//         // Poke the server to handle the negotiate call.
-//         auto Err = Server.handleOne();
-//         EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
-//       }
-
-//       {
-//         // Poke the server to handle the VoidBool call.
-//         auto Err = Server.handleOne();
-//         EXPECT_FALSE(!!Err) << "Server failed to handle call to void(bool)";
-//       }
-//   });
-
-//   {
-//     // Make an async call.
-//     auto Err = Client.callAsync<DummyRPCAPI::VoidBool>(
-//         [](Error Err) {
-//           EXPECT_FALSE(!!Err) << "Async void(bool) response handler failed";
-//           return Error::success();
-//         }, true);
-//     EXPECT_FALSE(!!Err) << "Client.callAsync failed for void(bool)";
-//   }
-
-//   {
-//     // Poke the client to process the result of the void(bool) call.
-//     auto Err = Client.handleOne();
-//     EXPECT_FALSE(!!Err) << "Client failed to handle response from void(bool)";
-//   }
-
-//   ServerThread.join();
-// }
-
-// TEST(DummyRPC, TestAsyncIntInt) {
-//   Queue Q1, Q2;
-//   DummyRPCEndpoint Client(Q1, Q2);
-//   DummyRPCEndpoint Server(Q2, Q1);
-
-//   std::thread ServerThread([&]() {
-//       Server.addHandler<DummyRPCAPI::IntInt>(
-//           [](int X) -> int {
-//             EXPECT_EQ(X, 21) << "Server int(int) receieved unexpected result";
-//             return 2 * X;
-//           });
-
-//       {
-//         // Poke the server to handle the negotiate call.
-//         auto Err = Server.handleOne();
-//         EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
-//       }
-
-//       {
-//         // Poke the server to handle the int(int) call.
-//         auto Err = Server.handleOne();
-//         EXPECT_FALSE(!!Err) << "Server failed to handle call to int(int)";
-//       }
-//     });
-
-//   {
-//     auto Err = Client.callAsync<DummyRPCAPI::IntInt>(
-//         [](Expected<int> Result) {
-//           EXPECT_TRUE(!!Result) << "Async int(int) response handler failed";
-//           EXPECT_EQ(*Result, 42)
-//             << "Async int(int) response handler received incorrect result";
-//           return Error::success();
-//         }, 21);
-//     EXPECT_FALSE(!!Err) << "Client.callAsync failed for int(int)";
-//   }
-
-//   {
-//     // Poke the client to process the result.
-//     auto Err = Client.handleOne();
-//     EXPECT_FALSE(!!Err) << "Client failed to handle response from void(bool)";
-//   }
-
-//   ServerThread.join();
-// }
-
-// TEST(DummyRPC, TestSerialization) {
-//   Queue Q1, Q2;
-//   DummyRPCEndpoint Client(Q1, Q2);
-//   DummyRPCEndpoint Server(Q2, Q1);
-
-//   std::thread ServerThread([&]() {
-//       Server.addHandler<DummyRPCAPI::AllTheTypes>(
-//           [&](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();
-//           });
-
-//       {
-//         // Poke the server to handle the negotiate call.
-//         auto Err = Server.handleOne();
-//         EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
-//       }
-
-//       {
-//         // Poke the server to handle the AllTheTypes call.
-//         auto Err = Server.handleOne();
-//         EXPECT_FALSE(!!Err) << "Server failed to handle call to void(bool)";
-//       }
-//     });
-
-
-//   {
-//     // Make an async call.
-//     std::vector<int> v({42, 7});
-//     auto Err = Client.callAsync<DummyRPCAPI::AllTheTypes>(
-//         [](Error Err) {
-//           EXPECT_FALSE(!!Err) << "Async AllTheTypes response handler failed";
-//           return Error::success();
-//         },
-//         static_cast<int8_t>(-101), static_cast<uint8_t>(250),
-//         static_cast<int16_t>(-10000), static_cast<uint16_t>(10000),
-//         static_cast<int32_t>(-1000000000), static_cast<uint32_t>(1000000000),
-//         static_cast<int64_t>(-10000000000), static_cast<uint64_t>(10000000000),
-//         true, std::string("foo"), v);
-//     EXPECT_FALSE(!!Err) << "Client.callAsync failed for AllTheTypes";
-//   }
-
-//   {
-//     // Poke the client to process the result of the AllTheTypes call.
-//     auto Err = Client.handleOne();
-//     EXPECT_FALSE(!!Err) << "Client failed to handle response from AllTheTypes";
-//   }
+TEST(DummyRPC, TestAsyncVoidBool) {
+  Queue Q1, Q2;
+  DummyRPCEndpoint Client(Q1, Q2);
+  DummyRPCEndpoint Server(Q2, Q1);
+
+  std::thread ServerThread([&]() {
+      Server.addHandler<DummyRPCAPI::VoidBool>(
+          [](bool B) {
+            EXPECT_EQ(B, true)
+              << "Server void(bool) received unexpected result";
+          });
+
+      {
+        // Poke the server to handle the negotiate call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
+      }
+
+      {
+        // Poke the server to handle the VoidBool call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to void(bool)";
+      }
+  });
+
+  {
+    // Make an async call.
+    auto Err = Client.callAsync<DummyRPCAPI::VoidBool>(
+        [](Error Err) {
+          EXPECT_FALSE(!!Err) << "Async void(bool) response handler failed";
+          return Error::success();
+        }, true);
+    EXPECT_FALSE(!!Err) << "Client.callAsync failed for void(bool)";
+  }
+
+  {
+    // Poke the client to process the result of the void(bool) call.
+    auto Err = Client.handleOne();
+    EXPECT_FALSE(!!Err) << "Client failed to handle response from void(bool)";
+  }
+
+  ServerThread.join();
+}
+
+TEST(DummyRPC, TestAsyncIntInt) {
+  Queue Q1, Q2;
+  DummyRPCEndpoint Client(Q1, Q2);
+  DummyRPCEndpoint Server(Q2, Q1);
+
+  std::thread ServerThread([&]() {
+      Server.addHandler<DummyRPCAPI::IntInt>(
+          [](int X) -> int {
+            EXPECT_EQ(X, 21) << "Server int(int) receieved unexpected result";
+            return 2 * X;
+          });
+
+      {
+        // Poke the server to handle the negotiate call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
+      }
+
+      {
+        // Poke the server to handle the int(int) call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to int(int)";
+      }
+    });
+
+  {
+    auto Err = Client.callAsync<DummyRPCAPI::IntInt>(
+        [](Expected<int> Result) {
+          EXPECT_TRUE(!!Result) << "Async int(int) response handler failed";
+          EXPECT_EQ(*Result, 42)
+            << "Async int(int) response handler received incorrect result";
+          return Error::success();
+        }, 21);
+    EXPECT_FALSE(!!Err) << "Client.callAsync failed for int(int)";
+  }
+
+  {
+    // Poke the client to process the result.
+    auto Err = Client.handleOne();
+    EXPECT_FALSE(!!Err) << "Client failed to handle response from void(bool)";
+  }
+
+  ServerThread.join();
+}
+
+TEST(DummyRPC, TestSerialization) {
+  Queue Q1, Q2;
+  DummyRPCEndpoint Client(Q1, Q2);
+  DummyRPCEndpoint Server(Q2, Q1);
+
+  std::thread ServerThread([&]() {
+      Server.addHandler<DummyRPCAPI::AllTheTypes>(
+          [&](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();
+          });
+
+      {
+        // Poke the server to handle the negotiate call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
+      }
+
+      {
+        // Poke the server to handle the AllTheTypes call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to void(bool)";
+      }
+    });
+
+
+  {
+    // Make an async call.
+    std::vector<int> v({42, 7});
+    auto Err = Client.callAsync<DummyRPCAPI::AllTheTypes>(
+        [](Error Err) {
+          EXPECT_FALSE(!!Err) << "Async AllTheTypes response handler failed";
+          return Error::success();
+        },
+        static_cast<int8_t>(-101), static_cast<uint8_t>(250),
+        static_cast<int16_t>(-10000), static_cast<uint16_t>(10000),
+        static_cast<int32_t>(-1000000000), static_cast<uint32_t>(1000000000),
+        static_cast<int64_t>(-10000000000), static_cast<uint64_t>(10000000000),
+        true, std::string("foo"), v);
+    EXPECT_FALSE(!!Err) << "Client.callAsync failed for AllTheTypes";
+  }
+
+  {
+    // Poke the client to process the result of the AllTheTypes call.
+    auto Err = Client.handleOne();
+    EXPECT_FALSE(!!Err) << "Client failed to handle response from AllTheTypes";
+  }
 
-//   ServerThread.join();
-// }
+  ServerThread.join();
+}
 
 // Test the synchronous call API.
 // TEST_F(DummyRPC, TestSynchronousCall) {




More information about the llvm-commits mailing list