Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1290)

Side by Side Diff: base/debug/activity_tracker.h

Issue 2387733002: Move memory management code into separate class for future reuse. (Closed)
Patch Set: object_free -> object_free_type Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/debug/activity_tracker.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Activity tracking provides a low-overhead method of collecting information 5 // Activity tracking provides a low-overhead method of collecting information
6 // about the state of the application for analysis both while it is running 6 // about the state of the application for analysis both while it is running
7 // and after it has terminated unexpectedly. Its primary purpose is to help 7 // and after it has terminated unexpectedly. Its primary purpose is to help
8 // locate reasons the browser becomes unresponsive by providing insight into 8 // locate reasons the browser becomes unresponsive by providing insight into
9 // what all the various threads and processes are (or were) doing. 9 // what all the various threads and processes are (or were) doing.
10 10
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 static ActivityData ForProcess(const int64_t id) { 118 static ActivityData ForProcess(const int64_t id) {
119 ActivityData data; 119 ActivityData data;
120 data.process.process_id = id; 120 data.process.process_id = id;
121 return data; 121 return data;
122 } 122 }
123 }; 123 };
124 124
125 // A "null" activity-data that can be passed to indicate "do not change". 125 // A "null" activity-data that can be passed to indicate "do not change".
126 extern const ActivityData kNullActivityData; 126 extern const ActivityData kNullActivityData;
127 127
128
129 // A helper class that is used for managing memory allocations within a
130 // persistent memory allocator. Instances of this class are NOT thread-safe.
131 // Use from a single thread or protect access with a lock.
132 class ActivityTrackerMemoryAllocator {
133 public:
134 using Reference = PersistentMemoryAllocator::Reference;
135
136 // Creates a instance for allocating objects of a fixed |object_type|, a
137 // corresponding |object_free| type, and the |object_size|. An internal
138 // cache of the last |cache_size| released references will be kept for
139 // quick future fetches.
140 ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator,
141 uint32_t object_type,
142 uint32_t object_free_type,
143 size_t object_size,
144 size_t cache_size);
145 ~ActivityTrackerMemoryAllocator();
146
147 // Gets a reference to an object of the configured type. This can return
148 // a null reference if it was not possible to allocate the memory.
149 Reference GetObjectReference();
150
151 // Returns an object to the "free" pool.
152 void ReleaseObjectReference(Reference ref);
153
154 // The current "used size" of the internal cache, visible for testing.
155 size_t cache_used() const { return cache_used_; }
156
157 private:
158 PersistentMemoryAllocator* const allocator_;
159 const uint32_t object_type_;
160 const uint32_t object_free_type_;
161 const size_t object_size_;
162 const size_t cache_size_;
163
164 // An iterator for going through persistent memory looking for free'd objects.
165 PersistentMemoryAllocator::Iterator iterator_;
166
167 // The cache of released object memories.
168 std::unique_ptr<Reference[]> cache_values_;
169 size_t cache_used_;
170
171 DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator);
172 };
173
174
128 // This structure is the full contents recorded for every activity pushed 175 // This structure is the full contents recorded for every activity pushed
129 // onto the stack. The |activity_type| indicates what is actually stored in 176 // onto the stack. The |activity_type| indicates what is actually stored in
130 // the |data| field. All fields must be explicitly sized types to ensure no 177 // the |data| field. All fields must be explicitly sized types to ensure no
131 // interoperability problems between 32-bit and 64-bit systems. 178 // interoperability problems between 32-bit and 64-bit systems.
132 struct Activity { 179 struct Activity {
133 // The type of an activity on the stack. Activities are broken into 180 // The type of an activity on the stack. Activities are broken into
134 // categories with the category ID taking the top 4 bits and the lower 181 // categories with the category ID taking the top 4 bits and the lower
135 // bits representing an action within that category. This combination 182 // bits representing an action within that category. This combination
136 // makes it easy to "switch" based on the type during analysis. 183 // makes it easy to "switch" based on the type during analysis.
137 enum Type : uint8_t { 184 enum Type : uint8_t {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 base::ThreadChecker thread_checker_; 384 base::ThreadChecker thread_checker_;
338 385
339 DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker); 386 DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker);
340 }; 387 };
341 388
342 389
343 // The global tracker manages all the individual thread trackers. Memory for 390 // The global tracker manages all the individual thread trackers. Memory for
344 // the thread trackers is taken from a PersistentMemoryAllocator which allows 391 // the thread trackers is taken from a PersistentMemoryAllocator which allows
345 // for the data to be analyzed by a parallel process or even post-mortem. 392 // for the data to be analyzed by a parallel process or even post-mortem.
346 class BASE_EXPORT GlobalActivityTracker { 393 class BASE_EXPORT GlobalActivityTracker {
347 template <typename T>
348 class ThreadSafeStack {
349 public:
350 ThreadSafeStack(size_t size)
351 : size_(size), values_(new T[size]), used_(0) {}
352 ~ThreadSafeStack() {}
353
354 size_t size() { return size_; }
355 size_t used() {
356 base::AutoLock autolock(lock_);
357 return used_;
358 }
359
360 bool push(T value) {
361 base::AutoLock autolock(lock_);
362 if (used_ == size_)
363 return false;
364 values_[used_++] = value;
365 return true;
366 }
367
368 bool pop(T* out_value) {
369 base::AutoLock autolock(lock_);
370 if (used_ == 0)
371 return false;
372 *out_value = values_[--used_];
373 return true;
374 }
375
376 private:
377 const size_t size_;
378
379 std::unique_ptr<T[]> values_;
380 size_t used_;
381 base::Lock lock_;
382
383 private:
384 DISALLOW_COPY_AND_ASSIGN(ThreadSafeStack);
385 };
386
387 public: 394 public:
388 // Type identifiers used when storing in persistent memory so they can be 395 // Type identifiers used when storing in persistent memory so they can be
389 // identified during extraction; the first 4 bytes of the SHA1 of the name 396 // identified during extraction; the first 4 bytes of the SHA1 of the name
390 // is used as a unique integer. A "version number" is added to the base 397 // is used as a unique integer. A "version number" is added to the base
391 // so that, if the structure of that object changes, stored older versions 398 // so that, if the structure of that object changes, stored older versions
392 // will be safely ignored. These are public so that an external process 399 // will be safely ignored. These are public so that an external process
393 // can recognize records of this type within an allocator. 400 // can recognize records of this type within an allocator.
394 enum : uint32_t { 401 enum : uint32_t {
395 kTypeIdActivityTracker = 0x5D7381AF + 1, // SHA1(ActivityTracker) v1 402 kTypeIdActivityTracker = 0x5D7381AF + 1, // SHA1(ActivityTracker) v1
396 kTypeIdActivityTrackerFree = 0x3F0272FB + 1, // SHA1(ActivityTrackerFree) 403 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
397 }; 404 };
398 405
399 // This is a thin wrapper around the thread-tracker's ScopedActivity that 406 // This is a thin wrapper around the thread-tracker's ScopedActivity that
400 // accesses the global tracker to provide some of the information, notably 407 // accesses the global tracker to provide some of the information, notably
401 // which thread-tracker to use. It is safe to create even if activity 408 // which thread-tracker to use. It is safe to create even if activity
402 // tracking is not enabled. 409 // tracking is not enabled.
403 class BASE_EXPORT ScopedThreadActivity 410 class BASE_EXPORT ScopedThreadActivity
404 : public ThreadActivityTracker::ScopedActivity { 411 : public ThreadActivityTracker::ScopedActivity {
405 public: 412 public:
406 ScopedThreadActivity(const void* origin, 413 ScopedThreadActivity(const void* origin,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 // Releases the activity-tracker for the current thread (for testing only). 499 // Releases the activity-tracker for the current thread (for testing only).
493 void ReleaseTrackerForCurrentThreadForTesting(); 500 void ReleaseTrackerForCurrentThreadForTesting();
494 501
495 private: 502 private:
496 friend class ActivityTrackerTest; 503 friend class ActivityTrackerTest;
497 504
498 enum : int { 505 enum : int {
499 // The maximum number of threads that can be tracked within a process. If 506 // The maximum number of threads that can be tracked within a process. If
500 // more than this number run concurrently, tracking of new ones may cease. 507 // more than this number run concurrently, tracking of new ones may cease.
501 kMaxThreadCount = 100, 508 kMaxThreadCount = 100,
509 kCachedThreadMemories = 10,
502 }; 510 };
503 511
504 // A thin wrapper around the main thread-tracker that keeps additional 512 // A thin wrapper around the main thread-tracker that keeps additional
505 // information that the global tracker needs to handle joined threads. 513 // information that the global tracker needs to handle joined threads.
506 class ManagedActivityTracker : public ThreadActivityTracker { 514 class ManagedActivityTracker : public ThreadActivityTracker {
507 public: 515 public:
508 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 516 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
509 void* base, 517 void* base,
510 size_t size); 518 size_t size);
511 ~ManagedActivityTracker() override; 519 ~ManagedActivityTracker() override;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 // The size (in bytes) of memory required by a ThreadActivityTracker to 551 // The size (in bytes) of memory required by a ThreadActivityTracker to
544 // provide the stack-depth requested during construction. 552 // provide the stack-depth requested during construction.
545 const size_t stack_memory_size_; 553 const size_t stack_memory_size_;
546 554
547 // The activity tracker for the currently executing thread. 555 // The activity tracker for the currently executing thread.
548 base::ThreadLocalStorage::Slot this_thread_tracker_; 556 base::ThreadLocalStorage::Slot this_thread_tracker_;
549 557
550 // The number of thread trackers currently active. 558 // The number of thread trackers currently active.
551 std::atomic<int> thread_tracker_count_; 559 std::atomic<int> thread_tracker_count_;
552 560
553 // A cache of thread-tracker memories that have been previously freed and 561 // A caching memory allocator for thread-tracker objects.
554 // thus can be re-used instead of allocating new ones. 562 ActivityTrackerMemoryAllocator thread_tracker_allocator_;
555 ThreadSafeStack<PersistentMemoryAllocator::Reference> available_memories_; 563 base::Lock thread_tracker_allocator_lock_;
556 564
557 // The active global activity tracker. 565 // The active global activity tracker.
558 static GlobalActivityTracker* g_tracker_; 566 static GlobalActivityTracker* g_tracker_;
559 567
560 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 568 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
561 }; 569 };
562 570
563 571
564 // Record entry in to and out of an arbitrary block of code. 572 // Record entry in to and out of an arbitrary block of code.
565 class BASE_EXPORT ScopedActivity 573 class BASE_EXPORT ScopedActivity
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 explicit ScopedProcessWaitActivity(const base::Process* process); 657 explicit ScopedProcessWaitActivity(const base::Process* process);
650 private: 658 private:
651 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 659 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
652 }; 660 };
653 #endif 661 #endif
654 662
655 } // namespace debug 663 } // namespace debug
656 } // namespace base 664 } // namespace base
657 665
658 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 666 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW
« no previous file with comments | « no previous file | base/debug/activity_tracker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698