summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-09-29 21:45:21 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-09-29 21:45:21 +0000
commit424723b281c8e4c861365e088cb2b392f1a209fb (patch)
treea6a591227d615e86c94ee6edc1cee359ceed672e /lldb/source
parent4ce469b7ea153e54a624b9359f25f8e62fad7db1 (diff)
downloadbcm5719-llvm-424723b281c8e4c861365e088cb2b392f1a209fb.tar.gz
bcm5719-llvm-424723b281c8e4c861365e088cb2b392f1a209fb.zip
thread state coordinator: add exec reset support, remove empty virtual destructors.
Also added a test for the reset handling. The reset/state clearing happens as a processed queue event. The only diff vs. standard processing is that the exec clears the queue before queueing the activity to clear internal state. i.e. once we get an exec, we really stop doing any other queue-based activity. llvm-svn: 218629
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp71
-rw-r--r--lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h17
2 files changed, 66 insertions, 22 deletions
diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
index 78b9abbd88a..b6d1382577d 100644
--- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
+++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp
@@ -49,10 +49,6 @@ public:
{
}
- ~EventStopCoordinator () override
- {
- }
-
bool
ProcessEvent(ThreadStateCoordinator &coordinator) override
{
@@ -77,10 +73,6 @@ public:
{
}
- ~EventCallAfterThreadsStop () override
- {
- }
-
lldb::tid_t GetTriggeringTID () const
{
return m_triggering_tid;
@@ -181,6 +173,24 @@ private:
//===----------------------------------------------------------------------===//
+class ThreadStateCoordinator::EventReset : public ThreadStateCoordinator::EventBase
+{
+public:
+ EventReset ():
+ EventBase ()
+ {
+ }
+
+ bool
+ ProcessEvent(ThreadStateCoordinator &coordinator) override
+ {
+ coordinator.ResetNow ();
+ return true;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+
class ThreadStateCoordinator::EventThreadStopped : public ThreadStateCoordinator::EventBase
{
public:
@@ -190,10 +200,6 @@ public:
{
}
- ~EventThreadStopped () override
- {
- }
-
bool
ProcessEvent(ThreadStateCoordinator &coordinator) override
{
@@ -217,10 +223,6 @@ public:
{
}
- ~EventThreadCreate () override
- {
- }
-
bool
ProcessEvent(ThreadStateCoordinator &coordinator) override
{
@@ -244,10 +246,6 @@ public:
{
}
- ~EventThreadDeath () override
- {
- }
-
bool
ProcessEvent(ThreadStateCoordinator &coordinator) override
{
@@ -387,6 +385,19 @@ ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid)
}
void
+ThreadStateCoordinator::ResetNow ()
+{
+ // Clear the pending notification if there was one.
+ m_pending_notification_sp.reset ();
+
+ // Clear the stop map - we no longer know anything about any thread state.
+ // The caller is expected to reset thread states for all threads, and we
+ // will assume anything we haven't heard about is running and requires a
+ // stop.
+ m_tid_stop_map.clear ();
+}
+
+void
ThreadStateCoordinator::Log (const char *format, ...)
{
va_list args;
@@ -416,6 +427,26 @@ ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid)
}
void
+ThreadStateCoordinator::ResetForExec ()
+{
+ std::lock_guard<std::mutex> lock (m_queue_mutex);
+
+ // Remove everything from the queue. This is the only
+ // state mutation that takes place outside the processing
+ // loop.
+ QueueType empty_queue;
+ m_event_queue.swap (empty_queue);
+
+ // Do the real clear behavior on the the queue to eliminate
+ // the chance that processing of a dequeued earlier event is
+ // overlapping with the clearing of state here. Push it
+ // directly because we need to have this happen with the lock,
+ // and so far I only have this one place that needs a no-lock
+ // variant.
+ m_event_queue.push (EventBaseSP (new EventReset ()));
+}
+
+void
ThreadStateCoordinator::StopCoordinator ()
{
EnqueueEvent (EventBaseSP (new EventStopCoordinator ()));
diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h
index 14399abfe08..f27dc67099f 100644
--- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h
+++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h
@@ -59,6 +59,14 @@ namespace lldb_private
void
NotifyThreadDeath (lldb::tid_t tid);
+ // Indicate the calling process did an exec and that the thread state
+ // should be 100% cleared.
+ //
+ // Note this will clear out any pending notifications, but will not stop
+ // a notification currently in progress via ProcessNextEvent().
+ void
+ ResetForExec ();
+
// Indicate when the coordinator should shut down.
void
StopCoordinator ();
@@ -77,11 +85,13 @@ namespace lldb_private
class EventBase;
class EventCallAfterThreadsStop;
- class EventStopCoordinator;
class EventThreadStopped;
class EventThreadCreate;
class EventThreadDeath;
+ class EventStopCoordinator;
+ class EventReset;
+
typedef std::shared_ptr<EventBase> EventBaseSP;
typedef std::queue<EventBaseSP> QueueType;
@@ -109,6 +119,9 @@ namespace lldb_private
ThreadDidDie (lldb::tid_t tid);
void
+ ResetNow ();
+
+ void
Log (const char *format, ...);
// Member variables.
@@ -116,7 +129,7 @@ namespace lldb_private
QueueType m_event_queue;
// For now we do simple read/write lock strategy with efficient wait-for-data.
- // We can replace with entirely non-blocking queue later but we still want the
+ // We can replace with an entirely non-blocking queue later but we still want the
// reader to sleep when nothing is available - this will be a bursty but infrequent
// event mechanism.
std::condition_variable m_queue_condition;
OpenPOWER on IntegriCloud