@@ -97,12 +97,6 @@ class ThreadPlanStack {
9797 // / generated.
9898 void ClearThreadCache ();
9999
100- bool IsTID (lldb::tid_t tid) {
101- return GetTID () == tid;
102- }
103- lldb::tid_t GetTID ();
104- void SetTID (lldb::tid_t tid);
105-
106100private:
107101 lldb::ThreadPlanSP DiscardPlanNoLock ();
108102 lldb::ThreadPlanSP GetCurrentPlanNoLock () const ;
@@ -122,9 +116,6 @@ class ThreadPlanStack {
122116 // completed plan checkpoints.
123117 std::unordered_map<size_t , PlanStack> m_completed_plan_store;
124118 mutable llvm::sys::RWMutex m_stack_mutex;
125-
126- // ThreadPlanStacks shouldn't be copied.
127- ThreadPlanStack (ThreadPlanStack &rhs) = delete ;
128119};
129120
130121class ThreadPlanStackMap {
@@ -139,35 +130,16 @@ class ThreadPlanStackMap {
139130 void AddThread (Thread &thread) {
140131 std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
141132 lldb::tid_t tid = thread.GetID ();
142- // If we already have a ThreadPlanStack for this thread, use it.
143- if (m_plans_list.find (tid) != m_plans_list.end ())
144- return ;
145-
146- m_plans_up_container.emplace_back (
147- std::make_unique<ThreadPlanStack>(thread));
148- m_plans_list.emplace (tid, m_plans_up_container.back ().get ());
133+ m_plans_list.emplace (tid, thread);
149134 }
150135
151136 bool RemoveTID (lldb::tid_t tid) {
152137 std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
153138 auto result = m_plans_list.find (tid);
154139 if (result == m_plans_list.end ())
155140 return false ;
156- ThreadPlanStack *removed_stack = result->second ;
141+ result->second . ThreadDestroyed ( nullptr ) ;
157142 m_plans_list.erase (result);
158- // Now find it in the stack storage:
159- auto end = m_plans_up_container.end ();
160- auto iter = std::find_if (m_plans_up_container.begin (), end,
161- [&] (std::unique_ptr<ThreadPlanStack> &stack) {
162- return stack->IsTID (tid);
163- });
164- if (iter == end)
165- return false ;
166-
167- // Then tell the stack its thread has been destroyed:
168- removed_stack->ThreadDestroyed (nullptr );
169- // And then remove it from the container so it goes away.
170- m_plans_up_container.erase (iter);
171143 return true ;
172144 }
173145
@@ -177,69 +149,22 @@ class ThreadPlanStackMap {
177149 if (result == m_plans_list.end ())
178150 return nullptr ;
179151 else
180- return result->second ;
152+ return & result->second ;
181153 }
182154
183155 // / Clear the Thread* cache that each ThreadPlan contains.
184156 // /
185157 // / This is useful in situations like when a new Thread list is being
186158 // / generated.
187159 void ClearThreadCache () {
188- std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
189160 for (auto &plan_list : m_plans_list)
190- plan_list.second ->ClearThreadCache ();
191- }
192-
193- // rename to Reactivate?
194- void Activate (ThreadPlanStack &stack) {
195- std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
196- // Remove this from the detached plan list:
197- auto end = m_detached_plans.end ();
198- auto iter = std::find_if (m_detached_plans.begin (), end,
199- [&] (ThreadPlanStack *elem) {
200- return elem == &stack; });
201- if (iter != end)
202- m_detached_plans.erase (iter);
203-
204- if (m_plans_list.find (stack.GetTID ()) == m_plans_list.end ())
205- m_plans_list.emplace (stack.GetTID (), &stack);
206- else
207- m_plans_list.at (stack.GetTID ()) = &stack;
208- }
209-
210- void ScanForDetachedPlanStacks () {
211- std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
212- llvm::SmallVector<lldb::tid_t , 2 > invalidated_tids;
213- for (auto &pair : m_plans_list)
214- if (pair.second ->GetTID () != pair.first )
215- invalidated_tids.push_back (pair.first );
216-
217- for (auto tid : invalidated_tids) {
218- auto it = m_plans_list.find (tid);
219- ThreadPlanStack *stack = it->second ;
220- m_plans_list.erase (it);
221- m_detached_plans.push_back (stack);
222- }
223- }
224-
225- // This gets the vector of pointers to thread plans that aren't
226- // currently running on a thread. This is generally for thread
227- // plans that represent asynchronous operations waiting to be
228- // scheduled.
229- // The vector will never have null ThreadPlanStacks in it.
230- lldb::ThreadPlanSP FindThreadPlanInStack (
231- llvm::function_ref<lldb::ThreadPlanSP(ThreadPlanStack &)> fn) {
232- std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
233- for (auto *stack : m_detached_plans)
234- if (auto plan = fn (*stack))
235- return plan;
236- return {};
161+ plan_list.second .ClearThreadCache ();
237162 }
238163
239164 void Clear () {
240165 std::lock_guard<std::recursive_mutex> guard (m_stack_map_mutex);
241166 for (auto &plan : m_plans_list)
242- plan.second -> ThreadDestroyed (nullptr );
167+ plan.second . ThreadDestroyed (nullptr );
243168 m_plans_list.clear ();
244169 }
245170
@@ -256,23 +181,8 @@ class ThreadPlanStackMap {
256181
257182private:
258183 Process &m_process;
259- // We don't want to make copies of these ThreadPlanStacks, there needs to be
260- // just one of these tracking each piece of work. But we need to move the
261- // work from "attached to a TID" state to "detached" state, which is most
262- // conveniently done by having organizing containers for each of the two
263- // states.
264- // To make it easy to move these non-copyable entities in and out of the
265- // organizing containers, we make the ThreadPlanStacks into unique_ptr's in a
266- // storage container - m_plans_up_container. Storing unique_ptrs means we
267- // can then use the pointer to the ThreadPlanStack in the "organizing"
268- // containers, the TID->Stack map m_plans_list, and the detached plans
269- // vector m_detached_plans.
270-
271- using PlansStore = std::vector<std::unique_ptr<ThreadPlanStack>>;
272- PlansStore m_plans_up_container;
273- std::vector<ThreadPlanStack *> m_detached_plans;
274184 mutable std::recursive_mutex m_stack_map_mutex;
275- using PlansList = std::unordered_map<lldb::tid_t , ThreadPlanStack * >;
185+ using PlansList = std::unordered_map<lldb::tid_t , ThreadPlanStack>;
276186 PlansList m_plans_list;
277187
278188};
0 commit comments