[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