[Lldb-commits] [lldb] r218555 - thread state coordinator: handle when prerequisite pending stop is already stopped.

Todd Fiala todd.fiala at gmail.com
Fri Sep 26 16:42:53 PDT 2014


Author: tfiala
Date: Fri Sep 26 18:42:53 2014
New Revision: 218555

URL: http://llvm.org/viewvc/llvm-project?rev=218555&view=rev
Log:
thread state coordinator: handle when prerequisite pending stop is already stopped.

Change includes new gtest and functionality.

Modified:
    lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp
    lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp

Modified: lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp?rev=218555&r1=218554&r2=218555&view=diff
==============================================================================
--- lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp (original)
+++ lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp Fri Sep 26 18:42:53 2014
@@ -110,3 +110,52 @@ TEST(ThreadStateCoordinatorTest, CallAft
     ASSERT_EQ (true, call_after_fired);
     ASSERT_EQ (TRIGGERING_TID, reported_firing_tid);
 }
+
+TEST(ThreadStateCoordinatorTest, CallAfterThreadsStopFiresWhenPendingAlreadyStopped)
+{
+    ThreadStateCoordinator coordinator(NOPLogger);
+
+    const lldb::tid_t TRIGGERING_TID = 4105;
+    const lldb::tid_t PENDING_STOP_TID = 3;
+
+    ThreadStateCoordinator::ThreadIDSet pending_stop_tids { PENDING_STOP_TID };
+
+    // Tell coordinator the pending stop tid is already stopped.
+    coordinator.NotifyThreadStop (PENDING_STOP_TID);
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // Now fire the deferred thread stop notification, indicating that the pending thread
+    // must be stopped before we notify.
+    bool call_after_fired = false;
+    lldb::tid_t reported_firing_tid = 0;
+
+    bool request_thread_stop_called = false;
+    lldb::tid_t request_thread_stop_tid = 0;
+
+    // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped.
+    coordinator.CallAfterThreadsStop (TRIGGERING_TID,
+                                      pending_stop_tids,
+                                      [&](lldb::tid_t tid) {
+                                          request_thread_stop_called = true;
+                                          request_thread_stop_tid = tid;
+
+                                      },
+                                      [&](lldb::tid_t tid) {
+                                          call_after_fired = true;
+                                          reported_firing_tid = tid;
+                                      });
+
+    // Neither trigger should have gone off yet.
+    ASSERT_EQ (false, call_after_fired);
+    ASSERT_EQ (false, request_thread_stop_called);
+
+    // Process next event.
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // The pending stop should *not* fire because the coordinator knows it has already stopped.
+    ASSERT_EQ (false, request_thread_stop_called);
+
+    // The deferred signal notification should have fired since all requirements were met.
+    ASSERT_EQ (true, call_after_fired);
+    ASSERT_EQ (TRIGGERING_TID, reported_firing_tid);
+}

Modified: lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp?rev=218555&r1=218554&r2=218555&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp Fri Sep 26 18:42:53 2014
@@ -94,12 +94,27 @@ public:
     bool
     ProcessEvent(ThreadStateCoordinator &coordinator) override
     {
-        // Request a stop for all the thread stops that are needed.
-        // In the future, we can keep track of which stops we're
-        // still waiting for, and can not re-issue for already
-        // requested stops.
+        // Request a stop for all the thread stops that need to be stopped
+        // and are not already known to be stopped.  Keep a list of all the
+        // threads from which we still need to hear a stop reply.
+
+        ThreadIDSet sent_tids;
         for (auto tid : m_wait_for_stop_tids)
-            m_request_thread_stop_func (tid);
+        {
+            // If we don't know about the thread's stop state or we
+            // know it is not stopped, we need to send it a stop request.
+            auto find_it = coordinator.m_tid_stop_map.find (tid);
+            if ((find_it == coordinator.m_tid_stop_map.end ()) || !find_it->second)
+            {
+                m_request_thread_stop_func (tid);
+                sent_tids.insert (tid);
+            }
+        }
+
+        // We only need to wait for the sent_tids - so swap our wait set
+        // to the sent tids.  The rest are already stopped and we won't
+        // be receiving stop notifications for them.
+        m_wait_for_stop_tids.swap (sent_tids);
 
         if (m_wait_for_stop_tids.empty ())
         {





More information about the lldb-commits mailing list