ThreadPlan.cpp revision 5f35a4be95aed0e5b2cb36f7d785bcbfc67284ae
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/Core/Debugger.h"
17#include "lldb/Core/Log.h"
18#include "lldb/Core/State.h"
19#include "lldb/Target/RegisterContext.h"
20#include "lldb/Target/Thread.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/Target.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// ThreadPlan constructor
29//----------------------------------------------------------------------
30ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) :
31    m_thread (thread),
32    m_stop_vote (stop_vote),
33    m_run_vote (run_vote),
34    m_kind (kind),
35    m_name (name),
36    m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
37    m_plan_complete (false),
38    m_plan_private (false),
39    m_okay_to_discard (true),
40    m_is_master_plan (false),
41    m_plan_succeeded(true)
42{
43    SetID (GetNextID());
44}
45
46//----------------------------------------------------------------------
47// Destructor
48//----------------------------------------------------------------------
49ThreadPlan::~ThreadPlan()
50{
51}
52
53bool
54ThreadPlan::IsPlanComplete ()
55{
56    Mutex::Locker locker(m_plan_complete_mutex);
57    return m_plan_complete;
58}
59
60void
61ThreadPlan::SetPlanComplete (bool success)
62{
63    Mutex::Locker locker(m_plan_complete_mutex);
64    m_plan_complete = true;
65    m_plan_succeeded = success;
66}
67
68bool
69ThreadPlan::MischiefManaged ()
70{
71    Mutex::Locker locker(m_plan_complete_mutex);
72    // Mark the plan is complete, but don't override the success flag.
73    m_plan_complete = true;
74    return true;
75}
76
77Vote
78ThreadPlan::ShouldReportStop (Event *event_ptr)
79{
80    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
81
82    if (m_stop_vote == eVoteNoOpinion)
83    {
84        ThreadPlan *prev_plan = GetPreviousPlan ();
85        if (prev_plan)
86        {
87            Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
88            if (log)
89                log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s",
90                             GetVoteAsCString (prev_vote));
91            return prev_vote;
92        }
93    }
94    if (log)
95        log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote));
96    return m_stop_vote;
97}
98
99Vote
100ThreadPlan::ShouldReportRun (Event *event_ptr)
101{
102    if (m_run_vote == eVoteNoOpinion)
103    {
104        ThreadPlan *prev_plan = GetPreviousPlan ();
105        if (prev_plan)
106            return prev_plan->ShouldReportRun (event_ptr);
107    }
108    return m_run_vote;
109}
110
111bool
112ThreadPlan::StopOthers ()
113{
114    ThreadPlan *prev_plan;
115    prev_plan = GetPreviousPlan ();
116    if (prev_plan == NULL)
117        return false;
118    else
119        return prev_plan->StopOthers();
120}
121
122void
123ThreadPlan::SetStopOthers (bool new_value)
124{
125	// SetStopOthers doesn't work up the hierarchy.  You have to set the
126    // explicit ThreadPlan you want to affect.
127}
128
129bool
130ThreadPlan::WillResume (StateType resume_state, bool current_plan)
131{
132    if (current_plan)
133    {
134        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
135
136        if (log)
137        {
138            RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
139            addr_t pc = reg_ctx->GetPC();
140            addr_t sp = reg_ctx->GetSP();
141            addr_t fp = reg_ctx->GetFP();
142            log->Printf("%s Thread #%u: tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
143                        "plan = '%s', state = %s, stop others = %d",
144                        __FUNCTION__,
145                        m_thread.GetIndexID(),
146                        m_thread.GetID(),
147                        (uint64_t)pc,
148                        (uint64_t)sp,
149                        (uint64_t)fp,
150                        m_name.c_str(),
151                        StateAsCString(resume_state),
152                        StopOthers());
153        }
154    }
155    return true;
156}
157
158lldb::user_id_t
159ThreadPlan::GetNextID()
160{
161    static uint32_t g_nextPlanID = 0;
162    return ++g_nextPlanID;
163}
164
165void
166ThreadPlan::DidPush()
167{
168}
169
170void
171ThreadPlan::WillPop()
172{
173}
174
175bool
176ThreadPlan::OkayToDiscard()
177{
178    if (!IsMasterPlan())
179        return true;
180    else
181        return m_okay_to_discard;
182}
183
184lldb::StateType
185ThreadPlan::RunState ()
186{
187    if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled())
188        return eStateStepping;
189    else
190        return GetPlanRunState();
191}
192