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

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

Issue 2422213002: Added support for storing arbitrary user data. (Closed)
Patch Set: some 'git cl format' changes Created 4 years, 1 month 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 | « base/debug/activity_analyzer_unittest.cc ('k') | 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
11 #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_ 11 #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_
12 #define BASE_DEBUG_ACTIVITY_TRACKER_H_ 12 #define BASE_DEBUG_ACTIVITY_TRACKER_H_
13 13
14 // std::atomic is undesired due to performance issues when used as global 14 // std::atomic is undesired due to performance issues when used as global
15 // variables. There are no such instances here. This module uses the 15 // variables. There are no such instances here. This module uses the
16 // PersistentMemoryAllocator which also uses std::atomic and is written 16 // PersistentMemoryAllocator which also uses std::atomic and is written
17 // by the same author. 17 // by the same author.
18 #include <atomic> 18 #include <atomic>
19 #include <map>
19 #include <memory> 20 #include <memory>
20 #include <string> 21 #include <string>
21 #include <vector> 22 #include <vector>
22 23
23 #include "base/base_export.h" 24 #include "base/base_export.h"
24 #include "base/compiler_specific.h" 25 #include "base/compiler_specific.h"
26 #include "base/gtest_prod_util.h"
25 #include "base/location.h" 27 #include "base/location.h"
26 #include "base/metrics/persistent_memory_allocator.h" 28 #include "base/metrics/persistent_memory_allocator.h"
27 #include "base/threading/platform_thread.h" 29 #include "base/threading/platform_thread.h"
28 #include "base/threading/thread_checker.h" 30 #include "base/threading/thread_checker.h"
29 #include "base/threading/thread_local_storage.h" 31 #include "base/threading/thread_local_storage.h"
30 32
31 namespace base { 33 namespace base {
32 34
33 struct PendingTask; 35 struct PendingTask;
34 36
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // A helper class that is used for managing memory allocations within a 131 // A helper class that is used for managing memory allocations within a
130 // persistent memory allocator. Instances of this class are NOT thread-safe. 132 // persistent memory allocator. Instances of this class are NOT thread-safe.
131 // Use from a single thread or protect access with a lock. 133 // Use from a single thread or protect access with a lock.
132 class ActivityTrackerMemoryAllocator { 134 class ActivityTrackerMemoryAllocator {
133 public: 135 public:
134 using Reference = PersistentMemoryAllocator::Reference; 136 using Reference = PersistentMemoryAllocator::Reference;
135 137
136 // Creates a instance for allocating objects of a fixed |object_type|, a 138 // Creates a instance for allocating objects of a fixed |object_type|, a
137 // corresponding |object_free| type, and the |object_size|. An internal 139 // corresponding |object_free| type, and the |object_size|. An internal
138 // cache of the last |cache_size| released references will be kept for 140 // cache of the last |cache_size| released references will be kept for
139 // quick future fetches. 141 // quick future fetches. If |make_iterable| then allocated objects will
142 // be marked "iterable" in the allocator.
140 ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator, 143 ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator,
141 uint32_t object_type, 144 uint32_t object_type,
142 uint32_t object_free_type, 145 uint32_t object_free_type,
143 size_t object_size, 146 size_t object_size,
144 size_t cache_size); 147 size_t cache_size,
148 bool make_iterable);
145 ~ActivityTrackerMemoryAllocator(); 149 ~ActivityTrackerMemoryAllocator();
146 150
147 // Gets a reference to an object of the configured type. This can return 151 // 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. 152 // a null reference if it was not possible to allocate the memory.
149 Reference GetObjectReference(); 153 Reference GetObjectReference();
150 154
151 // Returns an object to the "free" pool. 155 // Returns an object to the "free" pool.
152 void ReleaseObjectReference(Reference ref); 156 void ReleaseObjectReference(Reference ref);
153 157
154 // The current "used size" of the internal cache, visible for testing. 158 // The current "used size" of the internal cache, visible for testing.
155 size_t cache_used() const { return cache_used_; } 159 size_t cache_used() const { return cache_used_; }
156 160
157 private: 161 private:
158 PersistentMemoryAllocator* const allocator_; 162 PersistentMemoryAllocator* const allocator_;
159 const uint32_t object_type_; 163 const uint32_t object_type_;
160 const uint32_t object_free_type_; 164 const uint32_t object_free_type_;
161 const size_t object_size_; 165 const size_t object_size_;
162 const size_t cache_size_; 166 const size_t cache_size_;
167 const bool make_iterable_;
163 168
164 // An iterator for going through persistent memory looking for free'd objects. 169 // An iterator for going through persistent memory looking for free'd objects.
165 PersistentMemoryAllocator::Iterator iterator_; 170 PersistentMemoryAllocator::Iterator iterator_;
166 171
167 // The cache of released object memories. 172 // The cache of released object memories.
168 std::unique_ptr<Reference[]> cache_values_; 173 std::unique_ptr<Reference[]> cache_values_;
169 size_t cache_used_; 174 size_t cache_used_;
170 175
171 DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator); 176 DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator);
172 }; 177 };
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 // it null. 237 // it null.
233 uint64_t origin_address; 238 uint64_t origin_address;
234 239
235 // Array of program-counters that make up the top of the call stack. 240 // Array of program-counters that make up the top of the call stack.
236 // Despite the fixed size, this list is always null-terminated. Entries 241 // Despite the fixed size, this list is always null-terminated. Entries
237 // after the terminator have no meaning and may or may not also be null. 242 // after the terminator have no meaning and may or may not also be null.
238 // The list will be completely empty if call-stack collection is not 243 // The list will be completely empty if call-stack collection is not
239 // enabled. 244 // enabled.
240 uint64_t call_stack[kActivityCallStackSize]; 245 uint64_t call_stack[kActivityCallStackSize];
241 246
247 // Reference to arbitrary user data within the persistent memory segment.
248 uint32_t user_data;
249
242 // The (enumerated) type of the activity. This defines what fields of the 250 // The (enumerated) type of the activity. This defines what fields of the
243 // |data| record are valid. 251 // |data| record are valid.
244 uint8_t activity_type; 252 uint8_t activity_type;
245 253
246 // Padding to ensure that the next member begins on a 64-bit boundary 254 // Padding to ensure that the next member begins on a 64-bit boundary
247 // even on 32-bit builds which ensures inter-operability between CPU 255 // even on 32-bit builds which ensures inter-operability between CPU
248 // architectures. New fields can be taken from this space. 256 // architectures. New fields can be taken from this space.
249 uint8_t padding[7]; 257 uint8_t padding[3];
250 258
251 // Information specific to the |activity_type|. 259 // Information specific to the |activity_type|.
252 ActivityData data; 260 ActivityData data;
253 261
254 static void FillFrom(Activity* activity, 262 static void FillFrom(Activity* activity,
255 const void* program_counter, 263 const void* program_counter,
256 const void* origin, 264 const void* origin,
257 Type type, 265 Type type,
258 const ActivityData& data); 266 const ActivityData& data);
259 }; 267 };
(...skipping 20 matching lines...) Expand all
280 288
281 // The current stack of activities that are underway for this thread. It 289 // The current stack of activities that are underway for this thread. It
282 // is limited in its maximum size with later entries being left off. 290 // is limited in its maximum size with later entries being left off.
283 std::vector<Activity> activity_stack; 291 std::vector<Activity> activity_stack;
284 292
285 // The current total depth of the activity stack, including those later 293 // The current total depth of the activity stack, including those later
286 // entries not recorded in the |activity_stack| vector. 294 // entries not recorded in the |activity_stack| vector.
287 uint32_t activity_stack_depth = 0; 295 uint32_t activity_stack_depth = 0;
288 }; 296 };
289 297
298 // This class manages arbitrary user data that can be associated with activities
299 // done by a thread by supporting key/value pairs of any type. This can provide
300 // additional information during debugging. It is also used to store arbitrary
301 // global data. All updates must be done from the same thread.
302 class BASE_EXPORT ActivityUserData {
303 // List of known value type. REFERENCE types must immediately follow the non-
304 // external types.
305 enum ValueType : uint8_t {
306 END_OF_VALUES = 0,
307 RAW_VALUE,
308 RAW_VALUE_REFERENCE,
309 STRING_VALUE,
310 STRING_VALUE_REFERENCE,
311 CHAR_VALUE,
312 SIGNED_VALUE,
313 UNSIGNED_VALUE,
314 };
315
316 public:
317 ActivityUserData(void* memory, size_t size);
318 ~ActivityUserData();
319
320 // Writes a |value| (as part of a key/value pair) that will be included with
321 // the activity in any reports. The same |name| can be written multiple times
322 // with each successive call overwriting the previously stored |value|. For
323 // raw and string values, the maximum size of successive writes is limited by
324 // the first call. The length of "name" is limited to 255 characters.
325 //
326 // This information is stored on a "best effort" basis. It may be dropped if
327 // the memory buffer is full or the associated activity is beyond the maximum
328 // recording depth.
329 void Set(StringPiece name, const void* memory, size_t size) {
330 Set(name, RAW_VALUE, memory, size);
331 }
332 void SetString(StringPiece name, StringPiece value) {
333 Set(name, STRING_VALUE, value.data(), value.length());
334 }
335 void SetChar(StringPiece name, char value) {
336 Set(name, CHAR_VALUE, &value, sizeof(value));
337 }
338 void SetInt(StringPiece name, int64_t value) {
339 Set(name, SIGNED_VALUE, &value, sizeof(value));
340 }
341 void SetUint(StringPiece name, uint64_t value) {
342 Set(name, UNSIGNED_VALUE, &value, sizeof(value));
343 }
344
345 // These function as above but don't actually copy the data into the
346 // persistent memory. They store unaltered pointers along with a size. These
347 // can be used in conjuction with a memory dump to find certain large pieces
348 // of information.
349 void SetReference(StringPiece name, const void* memory, size_t size) {
350 SetReference(name, RAW_VALUE_REFERENCE, memory, size);
351 }
352 void SetStringReference(StringPiece name, StringPiece value) {
353 SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length());
354 }
355
356 private:
357 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);
358
359 enum : size_t { kMemoryAlignment = sizeof(uint64_t) };
360
361 // A structure used to reference data held outside of persistent memory.
362 struct ReferenceRecord {
363 uint64_t address;
364 uint64_t size;
365 };
366
367 // Header to a key/value record held in persistent memory.
368 struct Header {
369 std::atomic<uint8_t> type; // Encoded ValueType
370 uint8_t name_size; // Length of "name" key.
371 std::atomic<uint16_t> value_size; // Actual size of of the stored value.
372 uint16_t record_size; // Total storage of name, value, header.
373 };
374
375 // This record is used to hold known value is a map so that they can be
376 // found and overwritten later.
377 struct ValueInfo {
378 ValueInfo();
379 ValueInfo(ValueInfo&&);
380 ~ValueInfo();
381
382 StringPiece name; // The "key" of the record.
383 ValueType type; // The type of the value.
384 void* memory; // Where the "value" is held.
385 std::atomic<uint16_t>* size_ptr; // Address of the actual size of value.
386 size_t extent; // The total storage of the value,
387 }; // typically rounded up for alignment.
388
389 void Set(StringPiece name, ValueType type, const void* memory, size_t size);
390 void SetReference(StringPiece name,
391 ValueType type,
392 const void* memory,
393 size_t size);
394
395 // TODO(bcwhite): Add Get() methods for Analyzer to use.
396
397 std::map<StringPiece, ValueInfo> values_;
398
399 char* memory_;
400 size_t available_;
401
402 base::ThreadChecker thread_checker_;
403
404 DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
405 };
290 406
291 // This class manages tracking a stack of activities for a single thread in 407 // This class manages tracking a stack of activities for a single thread in
292 // a persistent manner, implementing a bounded-size stack in a fixed-size 408 // a persistent manner, implementing a bounded-size stack in a fixed-size
293 // memory allocation. In order to support an operational mode where another 409 // memory allocation. In order to support an operational mode where another
294 // thread is analyzing this data in real-time, atomic operations are used 410 // thread is analyzing this data in real-time, atomic operations are used
295 // where necessary to guarantee a consistent view from the outside. 411 // where necessary to guarantee a consistent view from the outside.
296 // 412 //
297 // This class is not generally used directly but instead managed by the 413 // This class is not generally used directly but instead managed by the
298 // GlobalActivityTracker instance and updated using Scoped*Activity local 414 // GlobalActivityTracker instance and updated using Scoped*Activity local
299 // objects. 415 // objects.
300 class BASE_EXPORT ThreadActivityTracker { 416 class BASE_EXPORT ThreadActivityTracker {
301 public: 417 public:
418 using ActivityId = uint32_t;
419
302 // This is the base class for having the compiler manage an activity on the 420 // This is the base class for having the compiler manage an activity on the
303 // tracker's stack. It does nothing but call methods on the passed |tracker| 421 // tracker's stack. It does nothing but call methods on the passed |tracker|
304 // if it is not null, making it safe (and cheap) to create these objects 422 // if it is not null, making it safe (and cheap) to create these objects
305 // even if activity tracking is not enabled. 423 // even if activity tracking is not enabled.
306 class BASE_EXPORT ScopedActivity { 424 class BASE_EXPORT ScopedActivity {
307 public: 425 public:
308 ScopedActivity(ThreadActivityTracker* tracker, 426 ScopedActivity(ThreadActivityTracker* tracker,
309 const void* program_counter, 427 const void* program_counter,
310 const void* origin, 428 const void* origin,
311 Activity::Type type, 429 Activity::Type type,
312 const ActivityData& data) 430 const ActivityData& data);
313 : tracker_(tracker) { 431 ~ScopedActivity();
314 if (tracker_)
315 tracker_->PushActivity(program_counter, origin, type, data);
316 }
317 432
318 ~ScopedActivity() { 433 // Changes some basic metadata about the activity.
319 if (tracker_) 434 void ChangeTypeAndData(Activity::Type type, const ActivityData& data);
320 tracker_->PopActivity();
321 }
322 435
323 void ChangeTypeAndData(Activity::Type type, const ActivityData& data) { 436 // Returns an object for manipulating user data.
324 if (tracker_) 437 ActivityUserData& user_data();
325 tracker_->ChangeActivity(type, data);
326 }
327 438
328 private: 439 private:
329 // The thread tracker to which this object reports. It can be null if 440 // The thread tracker to which this object reports. It can be null if
330 // activity tracking is not (yet) enabled. 441 // activity tracking is not (yet) enabled.
331 ThreadActivityTracker* const tracker_; 442 ThreadActivityTracker* const tracker_;
332 443
444 // An identifier that indicates a specific activity on the stack.
445 ActivityId activity_id_;
446
447 // An object that manages additional user data, created only upon request.
448 std::unique_ptr<ActivityUserData> user_data_;
449
333 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); 450 DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
334 }; 451 };
335 452
336 // A ThreadActivityTracker runs on top of memory that is managed externally. 453 // A ThreadActivityTracker runs on top of memory that is managed externally.
337 // It must be large enough for the internal header and a few Activity 454 // It must be large enough for the internal header and a few Activity
338 // blocks. See SizeForStackDepth(). 455 // blocks. See SizeForStackDepth().
339 ThreadActivityTracker(void* base, size_t size); 456 ThreadActivityTracker(void* base, size_t size);
340 virtual ~ThreadActivityTracker(); 457 virtual ~ThreadActivityTracker();
341 458
342 // Indicates that an activity has started from a given |origin| address in 459 // Indicates that an activity has started from a given |origin| address in
343 // the code, though it can be null if the creator's address is not known. 460 // the code, though it can be null if the creator's address is not known.
344 // The |type| and |data| describe the activity. |program_counter| should be 461 // The |type| and |data| describe the activity. |program_counter| should be
345 // the result of GetProgramCounter() where push is called. 462 // the result of GetProgramCounter() where push is called. Returned is an
346 void PushActivity(const void* program_counter, 463 // ID that can be used to adjust the pushed activity.
347 const void* origin, 464 ActivityId PushActivity(const void* program_counter,
348 Activity::Type type, 465 const void* origin,
349 const ActivityData& data); 466 Activity::Type type,
467 const ActivityData& data);
350 468
351 // An inlined version of the above that gets the program counter where it 469 // An inlined version of the above that gets the program counter where it
352 // is called. 470 // is called.
353 ALWAYS_INLINE 471 ALWAYS_INLINE
354 void PushActivity(const void* origin, 472 ActivityId PushActivity(const void* origin,
355 Activity::Type type, 473 Activity::Type type,
356 const ActivityData& data) { 474 const ActivityData& data) {
357 PushActivity(::tracked_objects::GetProgramCounter(), origin, type, data); 475 return PushActivity(::tracked_objects::GetProgramCounter(), origin, type,
476 data);
358 } 477 }
359 478
360 // Changes the activity |type| and |data| of the top-most entry on the stack. 479 // Changes the activity |type| and |data| of the top-most entry on the stack.
361 // This is useful if the information has changed and it is desireable to 480 // This is useful if the information has changed and it is desireable to
362 // track that change without creating a new stack entry. If the type is 481 // track that change without creating a new stack entry. If the type is
363 // ACT_NULL or the data is kNullActivityData then that value will remain 482 // ACT_NULL or the data is kNullActivityData then that value will remain
364 // unchanged. The type, if changed, must remain in the same category. 483 // unchanged. The type, if changed, must remain in the same category.
365 // Changing both is not atomic so a snapshot operation could occur between 484 // Changing both is not atomic so a snapshot operation could occur between
366 // the update of |type| and |data| or between update of |data| fields. 485 // the update of |type| and |data| or between update of |data| fields.
367 void ChangeActivity(Activity::Type type, const ActivityData& data); 486 void ChangeActivity(ActivityId id,
487 Activity::Type type,
488 const ActivityData& data);
368 489
369 // Indicates that an activity has completed. 490 // Indicates that an activity has completed.
370 void PopActivity(); 491 void PopActivity(ActivityId id);
492
493 // Returns an object capable of storing arbitrary user data.
494 std::unique_ptr<ActivityUserData> GetUserData(ActivityId id);
371 495
372 // Returns whether the current data is valid or not. It is not valid if 496 // Returns whether the current data is valid or not. It is not valid if
373 // corruption has been detected in the header or other data structures. 497 // corruption has been detected in the header or other data structures.
374 bool IsValid() const; 498 bool IsValid() const;
375 499
376 // Gets a copy of the tracker contents for analysis. Returns false if a 500 // Gets a copy of the tracker contents for analysis. Returns false if a
377 // snapshot was not possible, perhaps because the data is not valid; the 501 // snapshot was not possible, perhaps because the data is not valid; the
378 // contents of |output_snapshot| are undefined in that case. The current 502 // contents of |output_snapshot| are undefined in that case. The current
379 // implementation does not support concurrent snapshot operations. 503 // implementation does not support concurrent snapshot operations.
380 bool Snapshot(ActivitySnapshot* output_snapshot) const; 504 bool Snapshot(ActivitySnapshot* output_snapshot) const;
(...skipping 27 matching lines...) Expand all
408 // for the data to be analyzed by a parallel process or even post-mortem. 532 // for the data to be analyzed by a parallel process or even post-mortem.
409 class BASE_EXPORT GlobalActivityTracker { 533 class BASE_EXPORT GlobalActivityTracker {
410 public: 534 public:
411 // Type identifiers used when storing in persistent memory so they can be 535 // Type identifiers used when storing in persistent memory so they can be
412 // identified during extraction; the first 4 bytes of the SHA1 of the name 536 // identified during extraction; the first 4 bytes of the SHA1 of the name
413 // is used as a unique integer. A "version number" is added to the base 537 // is used as a unique integer. A "version number" is added to the base
414 // so that, if the structure of that object changes, stored older versions 538 // so that, if the structure of that object changes, stored older versions
415 // will be safely ignored. These are public so that an external process 539 // will be safely ignored. These are public so that an external process
416 // can recognize records of this type within an allocator. 540 // can recognize records of this type within an allocator.
417 enum : uint32_t { 541 enum : uint32_t {
418 kTypeIdActivityTracker = 0x5D7381AF + 2, // SHA1(ActivityTracker) v2 542 kTypeIdActivityTracker = 0x5D7381AF + 2, // SHA1(ActivityTracker) v2
543 kTypeIdUserDataRecord = 0x615EDDD7 + 1, // SHA1(UserDataRecord) v1
544 kTypeIdGlobalDataRecord = 0xAFE61ABE + 1, // SHA1(GlobalDataRecord) v1
545
419 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, 546 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
547 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
420 }; 548 };
421 549
422 // This is a thin wrapper around the thread-tracker's ScopedActivity that 550 // This is a thin wrapper around the thread-tracker's ScopedActivity that
423 // accesses the global tracker to provide some of the information, notably 551 // accesses the global tracker to provide some of the information, notably
424 // which thread-tracker to use. It is safe to create even if activity 552 // which thread-tracker to use. It is safe to create even if activity
425 // tracking is not enabled. 553 // tracking is not enabled.
426 class BASE_EXPORT ScopedThreadActivity 554 class BASE_EXPORT ScopedThreadActivity
427 : public ThreadActivityTracker::ScopedActivity { 555 : public ThreadActivityTracker::ScopedActivity {
428 public: 556 public:
429 ScopedThreadActivity(const void* program_counter, 557 ScopedThreadActivity(const void* program_counter,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 return tracker; 638 return tracker;
511 return CreateTrackerForCurrentThread(); 639 return CreateTrackerForCurrentThread();
512 } 640 }
513 641
514 // Creates an activity-tracker for the current thread. 642 // Creates an activity-tracker for the current thread.
515 ThreadActivityTracker* CreateTrackerForCurrentThread(); 643 ThreadActivityTracker* CreateTrackerForCurrentThread();
516 644
517 // Releases the activity-tracker for the current thread (for testing only). 645 // Releases the activity-tracker for the current thread (for testing only).
518 void ReleaseTrackerForCurrentThreadForTesting(); 646 void ReleaseTrackerForCurrentThreadForTesting();
519 647
648 // Gets a reference to memory for holding user-defined activity data. If
649 // the reference is valid, it's memory will be returned. If not, then a
650 // new reference will be created (and stored) and that memory returned.
651 void* GetUserDataMemory(PersistentMemoryAllocator::Reference* reference);
652
653 // Releases memory for user-defined activity data.
654 void ReleaseUserDataMemory(PersistentMemoryAllocator::Reference* reference);
655
656 // Accesses the global data record for storing arbitrary key/value pairs.
657 ActivityUserData& user_data() { return user_data_; }
658
520 private: 659 private:
521 friend class ActivityTrackerTest; 660 friend class ActivityTrackerTest;
522 661
523 enum : int { 662 enum : int {
524 // The maximum number of threads that can be tracked within a process. If 663 // The maximum number of threads that can be tracked within a process. If
525 // more than this number run concurrently, tracking of new ones may cease. 664 // more than this number run concurrently, tracking of new ones may cease.
526 kMaxThreadCount = 100, 665 kMaxThreadCount = 100,
527 kCachedThreadMemories = 10, 666 kCachedThreadMemories = 10,
667 kCachedUserDataMemories = 10,
528 }; 668 };
529 669
530 // A thin wrapper around the main thread-tracker that keeps additional 670 // A thin wrapper around the main thread-tracker that keeps additional
531 // information that the global tracker needs to handle joined threads. 671 // information that the global tracker needs to handle joined threads.
532 class ManagedActivityTracker : public ThreadActivityTracker { 672 class ManagedActivityTracker : public ThreadActivityTracker {
533 public: 673 public:
534 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 674 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
535 void* base, 675 void* base,
536 size_t size); 676 size_t size);
537 ~ManagedActivityTracker() override; 677 ~ManagedActivityTracker() override;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 // The activity tracker for the currently executing thread. 713 // The activity tracker for the currently executing thread.
574 base::ThreadLocalStorage::Slot this_thread_tracker_; 714 base::ThreadLocalStorage::Slot this_thread_tracker_;
575 715
576 // The number of thread trackers currently active. 716 // The number of thread trackers currently active.
577 std::atomic<int> thread_tracker_count_; 717 std::atomic<int> thread_tracker_count_;
578 718
579 // A caching memory allocator for thread-tracker objects. 719 // A caching memory allocator for thread-tracker objects.
580 ActivityTrackerMemoryAllocator thread_tracker_allocator_; 720 ActivityTrackerMemoryAllocator thread_tracker_allocator_;
581 base::Lock thread_tracker_allocator_lock_; 721 base::Lock thread_tracker_allocator_lock_;
582 722
723 // A caching memory allocator for user data attached to activity data.
724 ActivityTrackerMemoryAllocator user_data_allocator_;
725 base::Lock user_data_allocator_lock_;
726
727 // An object for holding global arbitrary key value pairs. Values must always
728 // be written from the main UI thread.
729 ActivityUserData user_data_;
730
583 // The active global activity tracker. 731 // The active global activity tracker.
584 static GlobalActivityTracker* g_tracker_; 732 static GlobalActivityTracker* g_tracker_;
585 733
586 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 734 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
587 }; 735 };
588 736
589 737
590 // Record entry in to and out of an arbitrary block of code. 738 // Record entry in to and out of an arbitrary block of code.
591 class BASE_EXPORT ScopedActivity 739 class BASE_EXPORT ScopedActivity
592 : public GlobalActivityTracker::ScopedThreadActivity { 740 : public GlobalActivityTracker::ScopedThreadActivity {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 ScopedProcessWaitActivity(const void* program_counter, 858 ScopedProcessWaitActivity(const void* program_counter,
711 const base::Process* process); 859 const base::Process* process);
712 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 860 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
713 }; 861 };
714 #endif 862 #endif
715 863
716 } // namespace debug 864 } // namespace debug
717 } // namespace base 865 } // namespace base
718 866
719 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 867 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW
« no previous file with comments | « base/debug/activity_analyzer_unittest.cc ('k') | base/debug/activity_tracker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698