summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-09-29 22:57:05 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-09-29 22:57:05 +0000
commite2109e732382ee5a8cc1e57cd54d9ecd2cfbb97a (patch)
treee12daf04b8f86d9cdbe6a15e2eb701c797cc2f07
parent6bddb8c3a57ad79849f97c5775479e00bafb0c7e (diff)
downloadbcm5719-llvm-e2109e732382ee5a8cc1e57cd54d9ecd2cfbb97a.tar.gz
bcm5719-llvm-e2109e732382ee5a8cc1e57cd54d9ecd2cfbb97a.zip
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. llvm-svn: 218638
-rw-r--r--lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp66
-rw-r--r--lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp48
-rw-r--r--lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h3
3 files changed, 116 insertions, 1 deletions
diff --git a/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp b/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp
index ddf82cc711a..f9ca339e4fa 100644
--- a/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp
+++ b/lldb/gtest/unittest/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp
@@ -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, DeferredNotificationRemovedByResetForExec)
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);
+}
diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
index b6d1382577d..cd5ad6df3da 100644
--- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
+++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
@@ -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 (lldb::tid_t tid)
}
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)));
diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h
index f27dc67099f..f2a5af3bafe 100644
--- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h
+++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h
@@ -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;
OpenPOWER on IntegriCloud