diff options
| author | Todd Fiala <todd.fiala@gmail.com> | 2014-09-29 21:45:21 +0000 |
|---|---|---|
| committer | Todd Fiala <todd.fiala@gmail.com> | 2014-09-29 21:45:21 +0000 |
| commit | 424723b281c8e4c861365e088cb2b392f1a209fb (patch) | |
| tree | a6a591227d615e86c94ee6edc1cee359ceed672e /lldb/source | |
| parent | 4ce469b7ea153e54a624b9359f25f8e62fad7db1 (diff) | |
| download | bcm5719-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.cpp | 71 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h | 17 |
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; |

