[PATCH] Using select for remote MCJIT messages

Renato Golin renato.golin at linaro.org
Thu Nov 28 14:50:52 PST 2013


Hi andrew.w.kaylor, chapuni,

Fixes PR18057.

Tests in ExecutionEngine/MCJIT/remote like:
 * multi-module-a.ll.script
 * test-fp-no-external-funcs-remote.ll.script
 * test-common-symbols-remote.ll.script
 * cross-module-a.ll.script
 * test-global-init-nonzero-remote.ll.script

Fail randomly on a Cortex-A15 buildbot with the Assert:

tools/lli/RemoteTargetExternal.cpp:144:
 void llvm::RemoteTargetExternal::Receive(llvm::LLIMessageType, uint64_t &): 
  Assertion `rc == 4 && "Error reading message type.

The reason was that the read/write was interrupted. Using the select guarantees we have something to read/write to the pipes.

http://llvm-reviews.chandlerc.com/D2287

Files:
  tools/lli/Unix/RemoteTargetExternal.inc

Index: tools/lli/Unix/RemoteTargetExternal.inc
===================================================================
--- tools/lli/Unix/RemoteTargetExternal.inc
+++ tools/lli/Unix/RemoteTargetExternal.inc
@@ -78,11 +78,61 @@
 }
 
 int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) {
-  return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size);
+  int BytesRemaining = Size;
+  fd_set Fds;
+  FD_ZERO(&Fds);
+  FD_SET(((ConnectionData_t*)ConnectionData)->OutputPipe, &Fds);
+  int millisec = 1000;
+  struct timeval tv = { 0, 100*millisec };
+
+  int Ret, Counter = 8;
+  const uint8_t *Buf = (const uint8_t*)Data;
+  while (BytesRemaining > 0) {
+    // Make sure the pipe is ready for writing
+    Ret = select(1, NULL, &Fds, NULL, &tv);
+    // We don't want to block for too long, but we do want to try a few times
+    if (Ret == -1 && Counter--)
+      continue;
+
+    int BytesWritten = write(((ConnectionData_t*)ConnectionData)->OutputPipe,
+                              Buf, BytesRemaining);
+    // By now, because of the select, we *should* have had something
+    if (BytesWritten < 0)
+      return BytesWritten;
+
+    Buf += BytesWritten;
+    BytesRemaining -= BytesWritten;
+  }
+  return Size;
 }
 
 int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) {
-  return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
+  int BytesRemaining = Size;
+  fd_set Fds;
+  FD_ZERO(&Fds);
+  FD_SET(((ConnectionData_t*)ConnectionData)->InputPipe, &Fds);
+  int millisec = 1000;
+  struct timeval tv = { 0, 100*millisec };
+
+  int Ret, Counter = 8;
+  uint8_t *Buf = (uint8_t*)Data;
+  while (BytesRemaining > 0) {
+    // Make sure the pipe is ready for reading
+    Ret = select(1, &Fds, NULL, NULL, &tv);
+    // We don't want to block for too long, but we do want to try a few times
+    if (Ret == -1 && Counter--)
+      continue;
+
+    int BytesRead = read(((ConnectionData_t*)ConnectionData)->InputPipe,
+                         Buf, BytesRemaining);
+    // By now, because of the select, we *should* have had something
+    if (BytesRead < 0)
+      return BytesRead;
+
+    Buf += BytesRead;
+    BytesRemaining -= BytesRead;
+  }
+  return Size;
 }
 
 void RemoteTargetExternal::Wait() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2287.1.patch
Type: text/x-patch
Size: 2267 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131128/5b7cdac9/attachment.bin>


More information about the llvm-commits mailing list