Skip to content

[lldb][NFC] Remove vestigial downstream changes related to ThreadPlan migration #10000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -2380,18 +2380,6 @@ bool PruneThreadPlansForTID(lldb::tid_t tid);
/// Prune ThreadPlanStacks for all unreported threads.
void PruneThreadPlans();

void SynchronizeThreadPlans();

/// From the detached thread plan stacks, find the first stack that explains
/// the stop represented by the thread and the event.
lldb::ThreadPlanSP FindDetachedPlanExplainingStop(Thread &thread, Event *event_ptr);

/// Helper function for FindDetachedPlanExplainingStop. Exists only to be
/// marked as a C++ friend of `ThreadPlan`.
lldb::ThreadPlanSP DoesStackExplainStopNoLock(ThreadPlanStack &stack,
Thread &thread,
Event *event_ptr);

/// Find the thread plan stack associated with thread with \a tid.
///
/// \param[in] tid
Expand Down
20 changes: 0 additions & 20 deletions lldb/include/lldb/Target/ThreadPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,26 +486,6 @@ class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>,
return m_takes_iteration_count;
}

bool IsTID(lldb::tid_t tid) { return tid == m_tid; }
bool HasTID() { return m_tid != LLDB_INVALID_THREAD_ID; }
lldb::tid_t GetTID() { return m_tid; }

void SetTID(lldb::tid_t tid) {
if (m_tid != tid) {
m_tid = tid;
ClearThreadCache();
}
}

void ClearTID() {
m_tid = LLDB_INVALID_THREAD_ID;
ClearThreadCache();
}

friend lldb::ThreadPlanSP
Process::DoesStackExplainStopNoLock(ThreadPlanStack &stack, Thread &thread,
Event *event_ptr);

protected:
// Constructors and Destructors
ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread,
Expand Down
102 changes: 6 additions & 96 deletions lldb/include/lldb/Target/ThreadPlanStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,6 @@ class ThreadPlanStack {
/// generated.
void ClearThreadCache();

bool IsTID(lldb::tid_t tid) {
return GetTID() == tid;
}
lldb::tid_t GetTID();
void SetTID(lldb::tid_t tid);

private:
lldb::ThreadPlanSP DiscardPlanNoLock();
lldb::ThreadPlanSP GetCurrentPlanNoLock() const;
Expand All @@ -122,9 +116,6 @@ class ThreadPlanStack {
// completed plan checkpoints.
std::unordered_map<size_t, PlanStack> m_completed_plan_store;
mutable llvm::sys::RWMutex m_stack_mutex;

// ThreadPlanStacks shouldn't be copied.
ThreadPlanStack(ThreadPlanStack &rhs) = delete;
};

class ThreadPlanStackMap {
Expand All @@ -139,35 +130,16 @@ class ThreadPlanStackMap {
void AddThread(Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
lldb::tid_t tid = thread.GetID();
// If we already have a ThreadPlanStack for this thread, use it.
if (m_plans_list.find(tid) != m_plans_list.end())
return;

m_plans_up_container.emplace_back(
std::make_unique<ThreadPlanStack>(thread));
m_plans_list.emplace(tid, m_plans_up_container.back().get());
m_plans_list.emplace(tid, thread);
}

bool RemoveTID(lldb::tid_t tid) {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
auto result = m_plans_list.find(tid);
if (result == m_plans_list.end())
return false;
ThreadPlanStack *removed_stack = result->second;
result->second.ThreadDestroyed(nullptr);
m_plans_list.erase(result);
// Now find it in the stack storage:
auto end = m_plans_up_container.end();
auto iter = std::find_if(m_plans_up_container.begin(), end,
[&] (std::unique_ptr<ThreadPlanStack> &stack) {
return stack->IsTID(tid);
});
if (iter == end)
return false;

// Then tell the stack its thread has been destroyed:
removed_stack->ThreadDestroyed(nullptr);
// And then remove it from the container so it goes away.
m_plans_up_container.erase(iter);
return true;
}

Expand All @@ -177,69 +149,22 @@ class ThreadPlanStackMap {
if (result == m_plans_list.end())
return nullptr;
else
return result->second;
return &result->second;
}

/// Clear the Thread* cache that each ThreadPlan contains.
///
/// This is useful in situations like when a new Thread list is being
/// generated.
void ClearThreadCache() {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
for (auto &plan_list : m_plans_list)
plan_list.second->ClearThreadCache();
}

// rename to Reactivate?
void Activate(ThreadPlanStack &stack) {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
// Remove this from the detached plan list:
auto end = m_detached_plans.end();
auto iter = std::find_if(m_detached_plans.begin(), end,
[&] (ThreadPlanStack *elem) {
return elem == &stack; });
if (iter != end)
m_detached_plans.erase(iter);

if (m_plans_list.find(stack.GetTID()) == m_plans_list.end())
m_plans_list.emplace(stack.GetTID(), &stack);
else
m_plans_list.at(stack.GetTID()) = &stack;
}

void ScanForDetachedPlanStacks() {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
llvm::SmallVector<lldb::tid_t, 2> invalidated_tids;
for (auto &pair : m_plans_list)
if (pair.second->GetTID() != pair.first)
invalidated_tids.push_back(pair.first);

for (auto tid : invalidated_tids) {
auto it = m_plans_list.find(tid);
ThreadPlanStack *stack = it->second;
m_plans_list.erase(it);
m_detached_plans.push_back(stack);
}
}

// This gets the vector of pointers to thread plans that aren't
// currently running on a thread. This is generally for thread
// plans that represent asynchronous operations waiting to be
// scheduled.
// The vector will never have null ThreadPlanStacks in it.
lldb::ThreadPlanSP FindThreadPlanInStack(
llvm::function_ref<lldb::ThreadPlanSP(ThreadPlanStack &)> fn) {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
for (auto *stack : m_detached_plans)
if (auto plan = fn(*stack))
return plan;
return {};
plan_list.second.ClearThreadCache();
}

void Clear() {
std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
for (auto &plan : m_plans_list)
plan.second->ThreadDestroyed(nullptr);
plan.second.ThreadDestroyed(nullptr);
m_plans_list.clear();
}

Expand All @@ -256,23 +181,8 @@ class ThreadPlanStackMap {

private:
Process &m_process;
// We don't want to make copies of these ThreadPlanStacks, there needs to be
// just one of these tracking each piece of work. But we need to move the
// work from "attached to a TID" state to "detached" state, which is most
// conveniently done by having organizing containers for each of the two
// states.
// To make it easy to move these non-copyable entities in and out of the
// organizing containers, we make the ThreadPlanStacks into unique_ptr's in a
// storage container - m_plans_up_container. Storing unique_ptrs means we
// can then use the pointer to the ThreadPlanStack in the "organizing"
// containers, the TID->Stack map m_plans_list, and the detached plans
// vector m_detached_plans.

using PlansStore = std::vector<std::unique_ptr<ThreadPlanStack>>;
PlansStore m_plans_up_container;
std::vector<ThreadPlanStack *> m_detached_plans;
mutable std::recursive_mutex m_stack_map_mutex;
using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack *>;
using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>;
PlansList m_plans_list;

};
Expand Down
32 changes: 1 addition & 31 deletions lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1373,34 +1373,6 @@ void Process::UpdateThreadListIfNeeded() {
}
}

void Process::SynchronizeThreadPlans() {
m_thread_plans.ScanForDetachedPlanStacks();
}

ThreadPlanSP Process::FindDetachedPlanExplainingStop(Thread &thread,
Event *event_ptr) {
return m_thread_plans.FindThreadPlanInStack(
[&](ThreadPlanStack &stack) -> ThreadPlanSP {
return DoesStackExplainStopNoLock(stack, thread, event_ptr);
});
}

// This extracted function only exists so that it can be marked a friend of
// `ThreadPlan`, which is needed to call `DoPlanExplainsStop`.
ThreadPlanSP Process::DoesStackExplainStopNoLock(ThreadPlanStack &stack,
Thread &thread,
Event *event_ptr) {
ThreadPlanSP plan_sp = stack.GetCurrentPlan();
plan_sp->SetTID(thread.GetID());
if (plan_sp->DoPlanExplainsStop(event_ptr)) {
stack.SetTID(thread.GetID());
m_thread_plans.Activate(stack);
return plan_sp;
}
plan_sp->ClearTID();
return {};
}

ThreadPlanStack *Process::FindThreadPlans(lldb::tid_t tid) {
return m_thread_plans.Find(tid);
}
Expand Down Expand Up @@ -3850,10 +3822,8 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
// restarted... Asking the thread list is also not likely to go well,
// since we are running again. So in that case just report the event.

if (!was_restarted) {
if (!was_restarted)
should_resume = !m_thread_list.ShouldStop(event_ptr);
SynchronizeThreadPlans();
}

if (was_restarted || should_resume || m_resume_requested) {
Vote report_stop_vote = m_thread_list.ShouldReportStop(event_ptr);
Expand Down
15 changes: 4 additions & 11 deletions lldb/source/Target/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,7 @@ void Thread::DidResume() {
void Thread::DidStop() { SetState(eStateStopped); }

bool Thread::ShouldStop(Event *event_ptr) {
ThreadPlan *current_plan = GetCurrentPlan();
bool should_stop = true;

Log *log = GetLog(LLDBLog::Step);
Expand Down Expand Up @@ -818,6 +819,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
LLDB_LOGF(log, "Plan stack initial state:\n%s", s.GetData());
}

// The top most plan always gets to do the trace log...
current_plan->DoTraceLog();

// First query the stop info's ShouldStopSynchronous. This handles
// "synchronous" stop reasons, for example the breakpoint command on internal
// breakpoints. If a synchronous stop reason says we should not stop, then
Expand All @@ -830,16 +834,6 @@ bool Thread::ShouldStop(Event *event_ptr) {
return false;
}

// Call this after ShouldStopSynchronous.
ThreadPlan *current_plan;
if (auto plan = GetProcess()->FindDetachedPlanExplainingStop(*this, event_ptr))
current_plan = plan.get();
else
current_plan = GetCurrentPlan();

// The top most plan always gets to do the trace log…
current_plan->DoTraceLog();

// If we've already been restarted, don't query the plans since the state
// they would examine is not current.
if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr))
Expand All @@ -856,7 +850,6 @@ bool Thread::ShouldStop(Event *event_ptr) {
// decide whether they still need to do more work.

bool done_processing_current_plan = false;

if (!current_plan->PlanExplainsStop(event_ptr)) {
if (current_plan->TracerExplainsStop()) {
done_processing_current_plan = true;
Expand Down
13 changes: 3 additions & 10 deletions lldb/source/Target/ThreadPlanStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,6 @@ void ThreadPlanStack::WillResume() {
m_discarded_plans.clear();
}

lldb::tid_t ThreadPlanStack::GetTID() { return GetCurrentPlan()->GetTID(); }

void ThreadPlanStack::SetTID(lldb::tid_t tid) {
for (auto plan_sp : m_plans)
plan_sp->SetTID(tid);
}

void ThreadPlanStackMap::Update(ThreadList &current_threads,
bool delete_missing,
bool check_for_new) {
Expand Down Expand Up @@ -469,8 +462,8 @@ void ThreadPlanStackMap::DumpPlans(Stream &strm,
index_id = thread_sp->GetIndexID();

if (condense_if_trivial) {
if (!elem.second->AnyPlans() && !elem.second->AnyCompletedPlans() &&
!elem.second->AnyDiscardedPlans()) {
if (!elem.second.AnyPlans() && !elem.second.AnyCompletedPlans() &&
!elem.second.AnyDiscardedPlans()) {
strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 "\n", index_id, tid);
strm.IndentMore();
strm.Indent();
Expand All @@ -483,7 +476,7 @@ void ThreadPlanStackMap::DumpPlans(Stream &strm,
strm.Indent();
strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 ":\n", index_id, tid);

elem.second->DumpThreadPlans(strm, desc_level, internal);
elem.second.DumpThreadPlans(strm, desc_level, internal);
}
}

Expand Down