Author: tfiala
Date: Mon Sep 29 17:57:05 2014
New Revision: 218638

URL: http://llvm.org/viewvc/llvm-project?rev=218638&view=rev
Log:
thread state coordinator: added a thread resume request and related tests.

The thread resume block is executed in the normal flow of thread
state queued event processing.  The tests verify that it is executed
when we track the thread to be stopped and skipped when we track
it to already be 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=218638&r1=218637&r2=218638&view=diff
==============================================================================
--- 
lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp 
(original)
+++ 
lldb/trunk/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp 
Mon Sep 29 17:57:05 2014
@@ -14,6 +14,14 @@ namespace
     {
         // Do nothing.
     }
+
+    void
+    StdoutLogger (const char *format, va_list args)
+    {
+        // Print to stdout.
+        vprintf (format, args);
+        printf ("\n");
+    }
 }
 
 TEST(ThreadStateCoordinatorTest, StopCoordinatorWorksNoPriorEvents)
@@ -433,3 +441,61 @@ TEST(ThreadStateCoordinatorTest, Deferre
     ASSERT_EQ (false, call_after_fired);
 }
 
+
+TEST(ThreadStateCoordinatorTest, 
RequestThreadResumeCallsCallbackWhenThreadIsStopped)
+{
+    ThreadStateCoordinator coordinator(NOPLogger);
+
+    // Initialize thread to be in stopped state.
+    const lldb::tid_t TEST_TID = 1234;
+
+    coordinator.NotifyThreadStop (TEST_TID);
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // Request a resume.
+    lldb::tid_t resumed_tid = 0;
+    int resume_call_count = 0;
+
+    coordinator.RequestThreadResume (TEST_TID,
+                                     [&](lldb::tid_t tid)
+                                     {
+                                         ++resume_call_count;
+                                         resumed_tid = tid;
+                                     });
+
+    // Shouldn't be called yet.
+    ASSERT_EQ (0, resume_call_count);
+
+    // Process next event.  After that, the resume request call should have 
fired.
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+    ASSERT_EQ (1, resume_call_count);
+    ASSERT_EQ (TEST_TID, resumed_tid);
+}
+
+TEST(ThreadStateCoordinatorTest, 
RequestThreadResumeIgnoresCallbackWhenThreadIsRunning)
+{
+    ThreadStateCoordinator coordinator(StdoutLogger);
+
+    // This thread will be assumed running (i.e. unknown, assumed running 
until marked stopped.)
+    const lldb::tid_t TEST_TID = 1234;
+
+    // Request a resume.
+    lldb::tid_t resumed_tid = 0;
+    int resume_call_count = 0;
+
+    coordinator.RequestThreadResume (TEST_TID,
+                                     [&](lldb::tid_t tid)
+                                     {
+                                         ++resume_call_count;
+                                         resumed_tid = tid;
+                                     });
+
+    // Shouldn't be called yet.
+    ASSERT_EQ (0, resume_call_count);
+
+    // Process next event.
+    ASSERT_EQ (true, coordinator.ProcessNextEvent ());
+
+    // The resume request should not have gone off because we think it is 
already running.
+    ASSERT_EQ (0, resume_call_count);
+}

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=218638&r1=218637&r2=218638&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp 
(original)
+++ lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp Mon Sep 
29 17:57:05 2014
@@ -260,6 +260,48 @@ private:
 
 
//===----------------------------------------------------------------------===//
 
+class ThreadStateCoordinator::EventRequestResume : public 
ThreadStateCoordinator::EventBase
+{
+public:
+    EventRequestResume (lldb::tid_t tid, const ThreadIDFunc 
&request_thread_resume_func):
+    EventBase (),
+    m_tid (tid),
+    m_request_thread_resume_func (request_thread_resume_func)
+    {
+    }
+
+    bool
+    ProcessEvent(ThreadStateCoordinator &coordinator) override
+    {
+        // Tell the thread to resume if we don't already think it is running.
+        auto find_it = coordinator.m_tid_stop_map.find (m_tid);
+        if (find_it == coordinator.m_tid_stop_map.end ())
+        {
+            // Skip the resume call - we think it is already running because 
we don't know anything about the thread.
+            coordinator.Log ("EventRequestResume::%s skipping resume request 
because we don't know about tid %" PRIu64 " and we therefore assume it is 
running.", __FUNCTION__, m_tid);
+            return true;
+        }
+        else if (!find_it->second)
+        {
+            // Skip the resume call - we have tracked it to be running.
+            coordinator.Log ("EventRequestResume::%s skipping resume request 
because tid %" PRIu64 " is already running according to our state tracking.", 
__FUNCTION__, m_tid);
+            return true;
+        }
+
+        // Request a resume.  We expect this to be synchronous and the system
+        // to reflect it is running after this completes.
+        m_request_thread_resume_func (m_tid);
+        return true;
+    }
+
+private:
+
+    const lldb::tid_t m_tid;
+    ThreadIDFunc m_request_thread_resume_func;
+};
+
+//===----------------------------------------------------------------------===//
+
 ThreadStateCoordinator::ThreadStateCoordinator (const LogFunc &log_func) :
     m_log_func (log_func),
     m_event_queue (),
@@ -415,6 +457,12 @@ ThreadStateCoordinator::NotifyThreadStop
 }
 
 void
+ThreadStateCoordinator::RequestThreadResume (lldb::tid_t tid, const 
ThreadIDFunc &request_thread_resume_func)
+{
+    EnqueueEvent (EventBaseSP (new EventRequestResume (tid, 
request_thread_resume_func)));
+}
+
+void
 ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid)
 {
     EnqueueEvent (EventBaseSP (new EventThreadCreate (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=218638&r1=218637&r2=218638&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h Mon Sep 29 
17:57:05 2014
@@ -51,7 +51,7 @@ namespace lldb_private
         NotifyThreadStop (lldb::tid_t tid);
 
         void
-        NotifyThreadResume (lldb::tid_t tid);
+        RequestThreadResume (lldb::tid_t tid, const ThreadIDFunc 
&request_thread_resume_func);
 
         void
         NotifyThreadCreate (lldb::tid_t tid);
@@ -88,6 +88,7 @@ namespace lldb_private
         class EventThreadStopped;
         class EventThreadCreate;
         class EventThreadDeath;
+        class EventRequestResume;
 
         class EventStopCoordinator;
         class EventReset;


_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to