1 //===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Target/ThreadPlan.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Target/Thread.h"
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/State.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 //----------------------------------------------------------------------
24 // ThreadPlan constructor
25 //----------------------------------------------------------------------
26 ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) :
27     m_kind (kind),
28     m_name (name),
29     m_thread (thread),
30     m_plan_complete(false),
31     m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
32     m_plan_private (false),
33     m_stop_vote (stop_vote),
34     m_run_vote (run_vote),
35     m_okay_to_discard (false)
36 {
37     SetID (GetNextID());
38 }
39 
40 //----------------------------------------------------------------------
41 // Destructor
42 //----------------------------------------------------------------------
43 ThreadPlan::~ThreadPlan()
44 {
45 }
46 
47 const char *
48 ThreadPlan::GetName () const
49 {
50     return m_name.c_str();
51 }
52 
53 Thread &
54 ThreadPlan::GetThread()
55 {
56     return m_thread;
57 }
58 
59 
60 const Thread &
61 ThreadPlan::GetThread() const
62 {
63     return m_thread;
64 }
65 
66 bool
67 ThreadPlan::IsPlanComplete ()
68 {
69     Mutex::Locker (m_plan_complete_mutex);
70     return m_plan_complete;
71 }
72 
73 void
74 ThreadPlan::SetPlanComplete ()
75 {
76     Mutex::Locker (m_plan_complete_mutex);
77     m_plan_complete = true;
78 }
79 
80 bool
81 ThreadPlan::MischiefManaged ()
82 {
83     Mutex::Locker (m_plan_complete_mutex);
84     m_plan_complete = true;
85     return true;
86 }
87 
88 Vote
89 ThreadPlan::ShouldReportStop (Event *event_ptr)
90 {
91     if (m_stop_vote == eVoteNoOpinion)
92     {
93         ThreadPlan *prev_plan = GetPreviousPlan ();
94         if (prev_plan)
95             return prev_plan->ShouldReportStop (event_ptr);
96     }
97     return m_stop_vote;
98 }
99 
100 Vote
101 ThreadPlan::ShouldReportRun (Event *event_ptr)
102 {
103     if (m_run_vote == eVoteNoOpinion)
104     {
105         ThreadPlan *prev_plan = GetPreviousPlan ();
106         if (prev_plan)
107             return prev_plan->ShouldReportRun (event_ptr);
108     }
109     return m_run_vote;
110 }
111 
112 bool
113 ThreadPlan::StopOthers ()
114 {
115     ThreadPlan *prev_plan;
116     prev_plan = GetPreviousPlan ();
117     if (prev_plan == NULL)
118         return false;
119     else
120         return prev_plan->StopOthers();
121 }
122 
123 bool
124 ThreadPlan::WillResume (StateType resume_state, bool current_plan)
125 {
126     if (current_plan)
127     {
128         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
129 
130         if (log)
131             log->Printf("Thread #%u: tid = 0x%4.4x about to resume the \"%s\" plan - state: %s - stop others: %d.",
132                         m_thread.GetIndexID(), m_thread.GetID(),  m_name.c_str(), StateAsCString(resume_state), StopOthers());
133     }
134     return true;
135 }
136 
137 lldb::user_id_t
138 ThreadPlan::GetNextID()
139 {
140     static uint32_t g_nextPlanID = 0;
141     return ++g_nextPlanID;
142 }
143 
144 void
145 ThreadPlan::DidPush()
146 {
147 }
148 
149 void
150 ThreadPlan::WillPop()
151 {
152 }
153 
154 void
155 ThreadPlan::PushPlan (ThreadPlanSP &thread_plan_sp)
156 {
157     m_thread.PushPlan (thread_plan_sp);
158 }
159 
160 ThreadPlan *
161 ThreadPlan::GetPreviousPlan ()
162 {
163     return m_thread.GetPreviousPlan (this);
164 }
165 
166 void
167 ThreadPlan::SetPrivate (bool input)
168 {
169     m_plan_private = input;
170 }
171 
172 bool
173 ThreadPlan::GetPrivate (void)
174 {
175     return m_plan_private;
176 }
177 
178 bool
179 ThreadPlan::OkayToDiscard()
180 {
181     if (!IsMasterPlan())
182         return true;
183     else
184         return m_okay_to_discard;
185 }
186 
187