summaryrefslogtreecommitdiff
path: root/source/Symbol/FuncUnwinders.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-01-08 21:19:00 +0000
committerGreg Clayton <gclayton@apple.com>2011-01-08 21:19:00 +0000
commit5382281cce4d2de419628a39b1284eca38b12d66 (patch)
treeb5876481d32a5be4b7ce756dfce0d554862fc908 /source/Symbol/FuncUnwinders.cpp
parent5d187e5495ee17f6763337a6ae28c2a7b07e4945 (diff)
Made FuncUnwinders threadsafe.
Other small cleanups as well. git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@123088 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'source/Symbol/FuncUnwinders.cpp')
-rw-r--r--source/Symbol/FuncUnwinders.cpp81
1 files changed, 67 insertions, 14 deletions
diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp
index 126ddd2ae..e09ad9201 100644
--- a/source/Symbol/FuncUnwinders.cpp
+++ b/source/Symbol/FuncUnwinders.cpp
@@ -33,14 +33,15 @@ FuncUnwinders::FuncUnwinders
m_unwind_table(unwind_table),
m_assembly_profiler(assembly_profiler),
m_range(range),
+ m_mutex (Mutex::eMutexTypeNormal),
m_unwind_at_call_site_ap (),
m_unwind_at_non_call_site_ap (),
- m_fast_unwind_ap (),
- m_arch_default_unwind (NULL),
+ m_unwind_fast_ap (),
+ m_unwind_arch_default (NULL),
m_tried_unwind_at_call_site (false),
m_tried_unwind_at_non_call_site (false),
- m_tried_fast_unwind (false),
- m_tried_arch_default_unwind (false),
+ m_tried_unwind_fast (false),
+ m_tried_unwind_arch_default (false),
m_first_non_prologue_insn()
{
}
@@ -52,6 +53,19 @@ FuncUnwinders::~FuncUnwinders ()
UnwindPlan*
FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset)
{
+ // Lock the mutex to ensure we can always give out the most appropriate
+ // information. We want to make sure if someone requests a call site unwind
+ // plan, that they get one and don't run into a race condition where one
+ // thread has started to create the unwind plan and has put it into
+ // m_unwind_at_call_site_ap, and have another thread enter this function
+ // and return the partially filled in m_unwind_at_call_site_ap pointer.
+ // We also want to make sure that we lock out other unwind plans from
+ // being accessed until this one is done creating itself in case someone
+ // had some code like:
+ // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+ // if (best_unwind_plan == NULL)
+ // best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+ Mutex::Locker locker (m_mutex);
if (m_tried_unwind_at_call_site == false && m_unwind_at_call_site_ap.get() == NULL)
{
m_tried_unwind_at_call_site = true;
@@ -82,6 +96,19 @@ FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset)
UnwindPlan*
FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
{
+ // Lock the mutex to ensure we can always give out the most appropriate
+ // information. We want to make sure if someone requests an unwind
+ // plan, that they get one and don't run into a race condition where one
+ // thread has started to create the unwind plan and has put it into
+ // the auto_ptr member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the auto_ptr.
+ // We also want to make sure that we lock out other unwind plans from
+ // being accessed until this one is done creating itself in case someone
+ // had some code like:
+ // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+ // if (best_unwind_plan == NULL)
+ // best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+ Mutex::Locker locker (m_mutex);
if (m_tried_unwind_at_non_call_site == false && m_unwind_at_non_call_site_ap.get() == NULL)
{
m_tried_unwind_at_non_call_site = true;
@@ -95,22 +122,48 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
UnwindPlan*
FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
{
- if (m_tried_fast_unwind == false && m_fast_unwind_ap.get() == NULL)
+ // Lock the mutex to ensure we can always give out the most appropriate
+ // information. We want to make sure if someone requests an unwind
+ // plan, that they get one and don't run into a race condition where one
+ // thread has started to create the unwind plan and has put it into
+ // the auto_ptr member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the auto_ptr.
+ // We also want to make sure that we lock out other unwind plans from
+ // being accessed until this one is done creating itself in case someone
+ // had some code like:
+ // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+ // if (best_unwind_plan == NULL)
+ // best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+ Mutex::Locker locker (m_mutex);
+ if (m_tried_unwind_fast == false && m_unwind_fast_ap.get() == NULL)
{
- m_tried_fast_unwind = true;
- m_fast_unwind_ap.reset (new UnwindPlan);
- if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_fast_unwind_ap))
- m_fast_unwind_ap.reset();
+ m_tried_unwind_fast = true;
+ m_unwind_fast_ap.reset (new UnwindPlan);
+ if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_fast_ap))
+ m_unwind_fast_ap.reset();
}
- return m_fast_unwind_ap.get();
+ return m_unwind_fast_ap.get();
}
UnwindPlan*
FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
{
- if (m_tried_arch_default_unwind == false && m_arch_default_unwind == NULL)
+ // Lock the mutex to ensure we can always give out the most appropriate
+ // information. We want to make sure if someone requests an unwind
+ // plan, that they get one and don't run into a race condition where one
+ // thread has started to create the unwind plan and has put it into
+ // the auto_ptr member variable, and have another thread enter this function
+ // and return the partially filled pointer contained in the auto_ptr.
+ // We also want to make sure that we lock out other unwind plans from
+ // being accessed until this one is done creating itself in case someone
+ // had some code like:
+ // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+ // if (best_unwind_plan == NULL)
+ // best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+ Mutex::Locker locker (m_mutex);
+ if (m_tried_unwind_arch_default == false && m_unwind_arch_default == NULL)
{
- m_tried_arch_default_unwind = true;
+ m_tried_unwind_arch_default = true;
Address current_pc;
Target *target = thread.CalculateTarget();
if (target)
@@ -118,11 +171,11 @@ FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
ArchSpec arch = target->GetArchitecture ();
ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
if (arch_default)
- m_arch_default_unwind = arch_default->GetArchDefaultUnwindPlan (thread, current_pc);
+ m_unwind_arch_default = arch_default->GetArchDefaultUnwindPlan (thread, current_pc);
}
}
- return m_arch_default_unwind;
+ return m_unwind_arch_default;
}
Address&