Added a speed test to the GDBRemoteCommunicationClient and 
GDBRemoteCommunicationServer classes. This involved adding a new packet
named "qSpeedTest" which can test the speed of a packet send/response pairs
using a wide variety of send/recv packet sizes.

Added a few new connection classes: one for shared memory, and one for using
mach messages (Apple only). The mach message stuff is experimental and not 
working yet, but added so I don't lose the code. The shared memory stuff
uses pretty standard calls to setup shared memory.




git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@128837 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 39efd35..d0198a0 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -765,9 +765,9 @@
 
 
 bool
-GDBRemoteCommunicationClient::GetHostInfo ()
+GDBRemoteCommunicationClient::GetHostInfo (bool force)
 {
-    if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+    if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
     {
         m_qHostInfo_is_valid = eLazyBoolNo;
         StringExtractorGDBRemote response;
@@ -1363,5 +1363,87 @@
         }
     }
     return false;
+}
 
+void
+GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
+{
+    uint32_t i;
+    TimeValue start_time, end_time;
+    uint64_t total_time_nsec;
+    float packets_per_second;
+    if (SendSpeedTestPacket (0, 0))
+    {
+        for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
+        {
+            for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
+            {
+                start_time = TimeValue::Now();
+                for (i=0; i<num_packets; ++i)
+                {
+                    SendSpeedTestPacket (send_size, recv_size);
+                }
+                end_time = TimeValue::Now();
+                total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
+                packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)NSEC_PER_SEC;
+                printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n", 
+                        num_packets, 
+                        send_size,
+                        recv_size,
+                        total_time_nsec / NSEC_PER_SEC, 
+                        total_time_nsec % NSEC_PER_SEC, 
+                        packets_per_second);
+                if (recv_size == 0)
+                    recv_size = 32;
+            }
+            if (send_size == 0)
+                send_size = 32;
+        }
+    }
+    else
+    {
+        start_time = TimeValue::Now();
+        for (i=0; i<num_packets; ++i)
+        {
+            GetCurrentProcessID ();
+        }
+        end_time = TimeValue::Now();
+        total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
+        packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)NSEC_PER_SEC;
+        printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n", 
+                num_packets, 
+                total_time_nsec / NSEC_PER_SEC, 
+                total_time_nsec % NSEC_PER_SEC, 
+                packets_per_second);
+    }
+}
+
+bool
+GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
+{
+    StreamString packet;
+    packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
+    uint32_t bytes_left = send_size;
+    while (bytes_left > 0)
+    {
+        if (bytes_left >= 26)
+        {
+            packet.PutCString("abcdefghijklmnopqrstuvwxyz");
+            bytes_left -= 26;
+        }
+        else
+        {
+            packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
+            bytes_left = 0;
+        }
+    }
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+    {
+        if (response.IsUnsupportedResponse())
+            return false;
+        return true;
+    }
+    return false;
 }
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index d28c827..ae1674a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -190,7 +190,7 @@
     ResetDiscoverableSettings();
 
     bool
-    GetHostInfo ();
+    GetHostInfo (bool force = false);
     
     bool
     GetOSVersion (uint32_t &major, 
@@ -246,6 +246,17 @@
         return old_packet_timeout;
     }
 
+    void
+    TestPacketSpeed (const uint32_t num_packets);
+
+    // This packet is for testing the speed of the interface only. Both
+    // the client and server need to support it, but this allows us to
+    // measure the packet speed without any other work being done on the
+    // other end and avoids any of that work affecting the packet send
+    // and response times.
+    bool
+    SendSpeedTestPacket (uint32_t send_size, 
+                         uint32_t recv_size);
 protected:
 
     //------------------------------------------------------------------
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index ea6842b..d6edbdd 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -117,6 +117,8 @@
         case StringExtractorGDBRemote::eServerPacketType_qGroupName:
             return Handle_qGroupName (packet);
 
+        case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
+            return Handle_qSpeedTest (packet);
         case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
             return Handle_QStartNoAckMode (packet);
         }
@@ -429,6 +431,42 @@
 }
 
 bool
+GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
+{
+    packet.SetFilePos(strlen ("qSpeedTest:"));
+
+    std::string key;
+    std::string value;
+    bool success = packet.GetNameColonValue(key, value);
+    if (success && key.compare("response_size") == 0)
+    {
+        uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success);
+        if (success)
+        {
+            if (response_size == 0)
+                return SendOKResponse();
+            StreamString response;
+            uint32_t bytes_left = response_size;
+            response.PutCString("data:");
+            while (bytes_left > 0)
+            {
+                if (bytes_left >= 26)
+                {
+                    response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+                    bytes_left -= 26;
+                }
+                else
+                {
+                    response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+                    bytes_left = 0;
+                }
+            }
+            return SendPacket (response);
+        }
+    }
+    return SendErrorResponse (7);
+}
+bool
 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
 {
     // Send response first before changing m_send_acks to we ack this packet
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 22fb7be..02440a2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -86,6 +86,9 @@
     Handle_qGroupName (StringExtractorGDBRemote &packet);
 
     bool
+    Handle_qSpeedTest (StringExtractorGDBRemote &packet);
+
+    bool
     Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
 
 private: