diff options
| author | Todd Fiala <todd.fiala@gmail.com> | 2014-09-27 01:58:13 +0000 |
|---|---|---|
| committer | Todd Fiala <todd.fiala@gmail.com> | 2014-09-27 01:58:13 +0000 |
| commit | ef5dbf55c83c4921576bc9946ad949ad5844a476 (patch) | |
| tree | dfc60621930b2fdae6a770b3af3f2cb38a1ffebb /lldb/source/Plugins/Process/Linux | |
| parent | 9dd7334d69f3b6cec8d8fa8e3759763d0379adb4 (diff) | |
| download | bcm5719-llvm-ef5dbf55c83c4921576bc9946ad949ad5844a476.tar.gz bcm5719-llvm-ef5dbf55c83c4921576bc9946ad949ad5844a476.zip | |
thread state coordinator: added thread death support and more tests.
Tested two pending stops before notification, where one of the pending stop
requirements was already known to be stopped.
Tested pending thread stop before notification, then reporting thread with
pending stop died and verifies pending notification is made.
llvm-svn: 218559
Diffstat (limited to 'lldb/source/Plugins/Process/Linux')
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp | 87 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h | 4 |
2 files changed, 81 insertions, 10 deletions
diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp index 8dfe03b1d6b..354dcc2bcc6 100644 --- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp +++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp @@ -133,14 +133,34 @@ public: return true; } + // Return true if still pending thread stops waiting; false if no more stops. + // If no more pending stops, signal. + bool + RemoveThreadStopRequirementAndMaybeSignal (lldb::tid_t tid) + { + // Remove this tid if it was in it. + m_wait_for_stop_tids.erase (tid); + + // Fire pending notification if no pending thread stops remain. + if (m_wait_for_stop_tids.empty ()) + { + // Fire the pending notification now. + NotifyNow (); + return false; + } + + // Still have pending thread stops. + return true; + } + +private: + void NotifyNow () { m_call_after_func (m_triggering_tid); } -private: - const lldb::tid_t m_triggering_tid; ThreadIDSet m_wait_for_stop_tids; ThreadIDFunc m_request_thread_stop_func; @@ -176,6 +196,33 @@ private: //===----------------------------------------------------------------------===// +class ThreadStateCoordinator::EventThreadDeath : public ThreadStateCoordinator::EventBase +{ +public: + EventThreadDeath (lldb::tid_t tid): + EventBase (), + m_tid (tid) + { + } + + ~EventThreadDeath () override + { + } + + bool + ProcessEvent(ThreadStateCoordinator &coordinator) override + { + coordinator.ThreadDidDie (m_tid); + return true; + } + +private: + + const lldb::tid_t m_tid; +}; + +//===----------------------------------------------------------------------===// + ThreadStateCoordinator::ThreadStateCoordinator (const LogFunc &log_func) : m_log_func (log_func), m_event_queue (), @@ -253,17 +300,31 @@ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid) // If we have a pending notification, remove this from the set. if (m_pending_notification_sp) { - EventCallAfterThreadsStop *call_after_event = static_cast<EventCallAfterThreadsStop*> (m_pending_notification_sp.get ()); + EventCallAfterThreadsStop *const call_after_event = static_cast<EventCallAfterThreadsStop*> (m_pending_notification_sp.get ()); + const bool pending_stops_remain = call_after_event->RemoveThreadStopRequirementAndMaybeSignal (tid); + if (!pending_stops_remain) + { + // Clear the pending notification now. + m_pending_notification_sp.reset (); + } + } +} - ThreadIDSet &remaining_stop_tids = call_after_event->GetRemainingWaitTIDs (); +void +ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid) +{ + // Update the global list of known thread states. While this one is stopped, it is also dead. + // So stop tracking it. We assume the user of this coordinator will not keep trying to add + // dependencies on a thread after it is known to be dead. + m_tid_stop_map.erase (tid); - // Remove this tid if it was in it. - remaining_stop_tids.erase (tid); - if (remaining_stop_tids.empty ()) + // If we have a pending notification, remove this from the set. + if (m_pending_notification_sp) + { + EventCallAfterThreadsStop *const call_after_event = static_cast<EventCallAfterThreadsStop*> (m_pending_notification_sp.get ()); + const bool pending_stops_remain = call_after_event->RemoveThreadStopRequirementAndMaybeSignal (tid); + if (!pending_stops_remain) { - // Fire the pending notification now. - call_after_event->NotifyNow (); - // Clear the pending notification now. m_pending_notification_sp.reset (); } @@ -288,6 +349,12 @@ ThreadStateCoordinator::NotifyThreadStop (lldb::tid_t tid) } void +ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid) +{ + EnqueueEvent (EventBaseSP (new EventThreadDeath (tid))); +} + +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 be1b70a33ea..6fecb1ce90a 100644 --- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h +++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h @@ -79,6 +79,7 @@ namespace lldb_private class EventCallAfterThreadsStop; class EventStopCoordinator; class EventThreadStopped; + class EventThreadDeath; typedef std::shared_ptr<EventBase> EventBaseSP; @@ -101,6 +102,9 @@ namespace lldb_private ThreadDidStop (lldb::tid_t tid); void + ThreadDidDie (lldb::tid_t tid); + + void Log (const char *format, ...); // Member variables. |

