Index: base/debug/activity_tracker.h |
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h |
index d6ff724cf2daee6106c3fbce75b9622f1d7a9eda..2cf48509301bf9b94109a98bda7cd30fc1652e28 100644 |
--- a/base/debug/activity_tracker.h |
+++ b/base/debug/activity_tracker.h |
@@ -23,6 +23,7 @@ |
#include "base/base_export.h" |
#include "base/location.h" |
#include "base/metrics/persistent_memory_allocator.h" |
+#include "base/threading/platform_thread.h" |
#include "base/threading/thread_checker.h" |
#include "base/threading/thread_local_storage.h" |
@@ -41,6 +42,7 @@ namespace debug { |
class ThreadActivityTracker; |
+ |
enum : int { |
// The maximum number of call-stack addresses stored per activity. This |
// cannot be changed without also changing the version number of the |
@@ -342,6 +344,46 @@ class BASE_EXPORT ThreadActivityTracker { |
// the thread trackers is taken from a PersistentMemoryAllocator which allows |
// for the data to be analyzed by a parallel process or even post-mortem. |
class BASE_EXPORT GlobalActivityTracker { |
+ template <typename T> |
+ class ThreadSafeStack { |
+ public: |
+ ThreadSafeStack(size_t size) |
+ : size_(size), values_(new T[size]), used_(0) {} |
+ ~ThreadSafeStack() {} |
+ |
+ size_t size() { return size_; } |
+ size_t used() { |
+ base::AutoLock autolock(lock_); |
+ return used_; |
+ } |
+ |
+ bool push(T value) { |
+ base::AutoLock autolock(lock_); |
+ if (used_ == size_) |
+ return false; |
+ values_[used_++] = value; |
+ return true; |
+ } |
+ |
+ bool pop(T* out_value) { |
+ base::AutoLock autolock(lock_); |
+ if (used_ == 0) |
+ return false; |
+ *out_value = values_[--used_]; |
+ return true; |
+ } |
+ |
+ private: |
+ const size_t size_; |
+ |
+ std::unique_ptr<T[]> values_; |
+ size_t used_; |
+ base::Lock lock_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ThreadSafeStack); |
+ }; |
+ |
public: |
// Type identifiers used when storing in persistent memory so they can be |
// identified during extraction; the first 4 bytes of the SHA1 of the name |
@@ -505,12 +547,12 @@ class BASE_EXPORT GlobalActivityTracker { |
// The activity tracker for the currently executing thread. |
base::ThreadLocalStorage::Slot this_thread_tracker_; |
- // These have to be lock-free because lock activity is tracked and causes |
- // re-entry problems. |
+ // The number of thread trackers currently active. |
std::atomic<int> thread_tracker_count_; |
- std::atomic<int> available_memories_count_; |
- std::atomic<PersistentMemoryAllocator::Reference> |
- available_memories_[kMaxThreadCount]; |
+ |
+ // A cache of thread-tracker memories that have been previously freed and |
+ // thus can be re-used instead of allocating new ones. |
+ ThreadSafeStack<PersistentMemoryAllocator::Reference> available_memories_; |
// The active global activity tracker. |
static GlobalActivityTracker* g_tracker_; |