diff options
author | Greg Clayton <gclayton@apple.com> | 2011-01-08 21:19:00 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-01-08 21:19:00 +0000 |
commit | 5382281cce4d2de419628a39b1284eca38b12d66 (patch) | |
tree | b5876481d32a5be4b7ce756dfce0d554862fc908 /source/Symbol/FuncUnwinders.cpp | |
parent | 5d187e5495ee17f6763337a6ae28c2a7b07e4945 (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.cpp | 81 |
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& |