[Lldb-commits] [lldb] r218578 - thread state coordinator: added new thread support.

Todd Fiala todd.fiala at gmail.com
Sat Sep 27 23:50:48 PDT 2014


Author: tfiala
Date: Sun Sep 28 01:50:47 2014
New Revision: 218578

URL: http://llvm.org/viewvc/llvm-project?rev=218578&view=rev
Log:
thread state coordinator: added new thread support.

A new thread arriving while a pending signal notification
is outstanding will (1) add the new thread to the list of
stops expected before the deferred signal notification is
fired, (2) send a stop request for the new thread, and
(3) track the new thread as currently running.

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

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=218578&r1=218577&r2=218578&view=diff
==============================================================================
--- lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp (original)
+++ lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp Sun Sep 28 01:50:47 2014
@@ -318,7 +318,7 @@ TEST(ThreadStateCoordinatorTest, CallAft
     ASSERT_EQ (true, request_thread_stop_called);
     ASSERT_EQ (PENDING_STOP_TID, request_thread_stop_tid);
 
-    // But we still shouldn't have the deferred signal call go off yet.  Need to wait for the stop to be reported.
+    // But we still shouldn't have the deferred signal call go off yet.  Need to wait for the death to be reported.
     ASSERT_EQ (false, call_after_fired);
 
     // Now report the that the thread with pending stop dies.
@@ -331,6 +331,74 @@ TEST(ThreadStateCoordinatorTest, CallAft
     ASSERT_EQ (true, coordinator.ProcessNextEvent ());
 
     // Deferred signal notification should have fired now.
+    ASSERT_EQ (true, call_after_fired);
+    ASSERT_EQ (TRIGGERING_TID, reported_firing_tid);
+}
+
+TEST(ThreadStateCoordinatorTest, ExistingPendingNotificationRequiresStopFromNewThread)
+{
+    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 };
+
+    bool call_after_fired = false;
+    lldb::tid_t reported_firing_tid = 0;
+
+    int request_thread_stop_calls = 0;
+    ThreadStateCoordinator::ThreadIDSet request_thread_stop_tids;
+
+    // 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_calls;
+                                          request_thread_stop_tids.insert (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 (0, request_thread_stop_calls);
+
+    // Process next event.
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // Now the request thread stop should have been called for the pending stop.
+    ASSERT_EQ (1, request_thread_stop_calls);
+    ASSERT_EQ (true, request_thread_stop_tids.count (PENDING_STOP_TID));
+
+    // But we still shouldn't have the deferred signal call go off yet.
+    ASSERT_EQ (false, call_after_fired);
+
+    // Indicate a new thread has just been created.
+    const lldb::tid_t NEW_THREAD_TID = 1234;
+
+    coordinator.NotifyThreadCreate (NEW_THREAD_TID);
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // We should have just received a stop request for the new thread id.
+    ASSERT_EQ (2, request_thread_stop_calls);
+    ASSERT_EQ (true, request_thread_stop_tids.count (NEW_THREAD_TID));
+
+    // Now report the original pending tid stopped.  This should no longer
+    // trigger the pending notification because we should now require the
+    // new thread to stop too.
+    coordinator.NotifyThreadStop (PENDING_STOP_TID);
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+    ASSERT_EQ (false, call_after_fired);
+
+    // Now notify the new thread stopped.
+    coordinator.NotifyThreadStop (NEW_THREAD_TID);
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // Deferred signal notification should have fired now.
     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=218578&r1=218577&r2=218578&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp Sun Sep 28 01:50:47 2014
@@ -153,6 +153,17 @@ public:
         return true;
     }
 
+    void
+    AddThreadStopRequirement (lldb::tid_t tid)
+    {
+        // Add this tid.
+        auto insert_result = m_wait_for_stop_tids.insert (tid);
+
+        // If it was really added, send the stop request to it.
+        if (insert_result.second)
+            m_request_thread_stop_func (tid);
+    }
+
 private:
 
     void
@@ -196,6 +207,33 @@ private:
 
 //===----------------------------------------------------------------------===//
 
+class ThreadStateCoordinator::EventThreadCreate : public ThreadStateCoordinator::EventBase
+{
+public:
+    EventThreadCreate (lldb::tid_t tid):
+    EventBase (),
+    m_tid (tid)
+    {
+    }
+
+    ~EventThreadCreate () override
+    {
+    }
+
+    bool
+    ProcessEvent(ThreadStateCoordinator &coordinator) override
+    {
+        coordinator.ThreadWasCreated (m_tid);
+        return true;
+    }
+
+private:
+
+    const lldb::tid_t m_tid;
+};
+
+//===----------------------------------------------------------------------===//
+
 class ThreadStateCoordinator::EventThreadDeath : public ThreadStateCoordinator::EventBase
 {
 public:
@@ -311,6 +349,22 @@ ThreadStateCoordinator::ThreadDidStop (l
 }
 
 void
+ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid)
+{
+    // Add the new thread to the stop map.
+    // We assume a created thread is not stopped.
+    m_tid_stop_map[tid] = false;
+
+    if (m_pending_notification_sp)
+    {
+        // Tell the pending notification that we need to wait
+        // for this new thread to stop.
+        EventCallAfterThreadsStop *const call_after_event = static_cast<EventCallAfterThreadsStop*> (m_pending_notification_sp.get ());
+        call_after_event->AddThreadStopRequirement (tid);
+    }
+}
+
+void
 ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid)
 {
     // Update the global list of known thread states.  While this one is stopped, it is also dead.
@@ -349,6 +403,12 @@ ThreadStateCoordinator::NotifyThreadStop
 }
 
 void
+ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid)
+{
+    EnqueueEvent (EventBaseSP (new EventThreadCreate (tid)));
+}
+
+void
 ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid)
 {
     EnqueueEvent (EventBaseSP (new EventThreadDeath (tid)));

Modified: lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h?rev=218578&r1=218577&r2=218578&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h Sun Sep 28 01:50:47 2014
@@ -79,6 +79,7 @@ namespace lldb_private
         class EventCallAfterThreadsStop;
         class EventStopCoordinator;
         class EventThreadStopped;
+        class EventThreadCreate;
         class EventThreadDeath;
 
         typedef std::shared_ptr<EventBase> EventBaseSP;
@@ -102,6 +103,9 @@ namespace lldb_private
         ThreadDidStop (lldb::tid_t tid);
 
         void
+        ThreadWasCreated (lldb::tid_t tid);
+
+        void
         ThreadDidDie (lldb::tid_t tid);
 
         void





More information about the lldb-commits mailing list