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

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

Issue 2422213002: Added support for storing arbitrary user data. (Closed)
Patch Set: plumb ActivityUserData all the way through 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
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"
25 #include "base/gtest_prod_util.h"
24 #include "base/location.h" 26 #include "base/location.h"
25 #include "base/metrics/persistent_memory_allocator.h" 27 #include "base/metrics/persistent_memory_allocator.h"
26 #include "base/threading/platform_thread.h" 28 #include "base/threading/platform_thread.h"
27 #include "base/threading/thread_checker.h" 29 #include "base/threading/thread_checker.h"
28 #include "base/threading/thread_local_storage.h" 30 #include "base/threading/thread_local_storage.h"
29 31
30 namespace base { 32 namespace base {
31 33
32 struct PendingTask; 34 struct PendingTask;
33 35
(...skipping 95 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 // it null. 234 // it null.
230 uint64_t origin_address; 235 uint64_t origin_address;
231 236
232 // Array of program-counters that make up the top of the call stack. 237 // Array of program-counters that make up the top of the call stack.
233 // Despite the fixed size, this list is always null-terminated. Entries 238 // Despite the fixed size, this list is always null-terminated. Entries
234 // after the terminator have no meaning and may or may not also be null. 239 // after the terminator have no meaning and may or may not also be null.
235 // The list will be completely empty if call-stack collection is not 240 // The list will be completely empty if call-stack collection is not
236 // enabled. 241 // enabled.
237 uint64_t call_stack[kActivityCallStackSize]; 242 uint64_t call_stack[kActivityCallStackSize];
238 243
244 // Reference to arbitrary user data within the persistent memory segment.
245 uint32_t user_data;
246
239 // The (enumerated) type of the activity. This defines what fields of the 247 // The (enumerated) type of the activity. This defines what fields of the
240 // |data| record are valid. 248 // |data| record are valid.
241 uint8_t activity_type; 249 uint8_t activity_type;
242 250
243 // Padding to ensure that the next member begins on a 64-bit boundary 251 // Padding to ensure that the next member begins on a 64-bit boundary
244 // even on 32-bit builds which ensures inter-operability between CPU 252 // even on 32-bit builds which ensures inter-operability between CPU
245 // architectures. New fields can be taken from this space. 253 // architectures. New fields can be taken from this space.
246 uint8_t padding[7]; 254 uint8_t padding[3];
247 255
248 // Information specific to the |activity_type|. 256 // Information specific to the |activity_type|.
249 ActivityData data; 257 ActivityData data;
250 258
251 static void FillFrom(Activity* activity, 259 static void FillFrom(Activity* activity,
252 const void* origin, 260 const void* origin,
253 Type type, 261 Type type,
254 const ActivityData& data); 262 const ActivityData& data);
255 }; 263 };
256 264
(...skipping 20 matching lines...) Expand all
277 // The current stack of activities that are underway for this thread. It 285 // The current stack of activities that are underway for this thread. It
278 // is limited in its maximum size with later entries being left off. 286 // is limited in its maximum size with later entries being left off.
279 std::vector<Activity> activity_stack; 287 std::vector<Activity> activity_stack;
280 288
281 // The current total depth of the activity stack, including those later 289 // The current total depth of the activity stack, including those later
282 // entries not recorded in the |activity_stack| vector. 290 // entries not recorded in the |activity_stack| vector.
283 uint32_t activity_stack_depth = 0; 291 uint32_t activity_stack_depth = 0;
284 }; 292 };
285 293
286 294
295 class BASE_EXPORT ActivityUserData {
manzagop (departed) 2016/11/11 17:01:42 nit: mention it's meant to be used on a single thr
manzagop (departed) 2016/11/11 17:01:42 Does this need atomic operations as well (to ensur
manzagop (departed) 2016/11/11 17:01:42 nit: class comment, perhaps with a high level ment
bcwhite 2016/11/14 15:08:42 Done.
bcwhite 2016/11/14 15:08:42 Done.
bcwhite 2016/11/14 15:08:42 Good point. I've gotten in to thinking only of th
296 // List of known value type. EXTERNAL types must immediately follow the non-
297 // external types.
298 enum ValueType : uint8_t {
299 EMPTY_VALUE,
300 RAW_VALUE,
301 EXTERNAL_RAW_VALUE,
manzagop (departed) 2016/11/11 17:01:42 Would RAW_VALUE_REFERENCE be more descriptive? I w
bcwhite 2016/11/14 15:08:42 I think that's better.
302 STRING_VALUE,
303 EXTERNAL_STRING_VALUE,
304 CHAR_VALUE,
305 SIGNED_VALUE,
306 UNSIGNED_VALUE,
307 };
308
309 public:
310 ActivityUserData(void* memory, size_t size);
311 ~ActivityUserData();
312
313 // Write the value (as part of a key/value pair) that will be included with
314 // the activity in any reports. The same |name| can be written multiple times
315 // with each successive call overwriting the previous value. The maximum size
manzagop (departed) 2016/11/11 17:01:42 nit: I think it could be clearer that it's the val
bcwhite 2016/11/14 15:08:42 Done.
316 // (for raw and string values) is limited by the first call, however.
manzagop (departed) 2016/11/11 17:01:42 Mention @pre name.length() <= std::numeric_limits<
manzagop (departed) 2016/11/11 17:01:42 Mention that if memory is lacking, the value may b
bcwhite 2016/11/14 15:08:42 Done.
bcwhite 2016/11/14 15:08:42 Done.
317 void Set(StringPiece name, const void* memory, size_t size) {
318 Set(name, RAW_VALUE, memory, size);
319 }
320 void SetString(StringPiece name, StringPiece value) {
321 Set(name, STRING_VALUE, value.data(), value.length());
322 }
323 void SetChar(StringPiece name, char value) {
324 Set(name, CHAR_VALUE, &value, sizeof(value));
325 }
326 void SetInt(StringPiece name, int64_t value) {
327 Set(name, SIGNED_VALUE, &value, sizeof(value));
328 }
329 void SetUint(StringPiece name, uint64_t value) {
330 Set(name, UNSIGNED_VALUE, &value, sizeof(value));
331 }
332
333 // These function as above but don't actually copy the data into the
334 // persistent memory. The store unaltered pointers along with a size that
manzagop (departed) 2016/11/11 17:01:42 typo: The -> They
bcwhite 2016/11/14 15:08:43 Done.
335 // can be used in conjuction with a memory dump to find certain pieces of
336 // information.
337 void SetExternal(StringPiece name, const void* memory, size_t size) {
338 SetExternal(name, EXTERNAL_RAW_VALUE, memory, size);
339 }
340 void SetExternalString(StringPiece name, StringPiece value) {
341 SetExternal(name, EXTERNAL_RAW_VALUE, value.data(), value.length());
342 }
343
344 private:
345 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);
346
347 enum : size_t { kMemoryAlignment = sizeof(uint64_t) };
348
349 struct ValueInfo {
350 ValueInfo();
351 ValueInfo(ValueInfo&&);
352 ~ValueInfo();
353
354 StringPiece name;
355 void* memory;
356 size_t size;
357 size_t extent;
manzagop (departed) 2016/11/11 17:01:42 I wasn't sure which of size/extent was which witho
bcwhite 2016/11/14 15:08:43 Done.
358 ValueType type;
359 };
360
361 struct Header {
362 uint8_t type;
363 uint8_t name_size;
364 uint16_t value_size;
manzagop (departed) 2016/11/11 17:01:42 Is this the size or the extent?
bcwhite 2016/11/14 15:08:42 Size. Comments added.
365 uint16_t record_size;
manzagop (departed) 2016/11/11 17:01:42 Comment on whether inclusive of header size?
bcwhite 2016/11/14 15:08:42 Inclusive.
366 };
367
368 struct ExternalRecord {
369 uint64_t address;
370 uint64_t size;
371 };
372
373 void Set(StringPiece name, ValueType type, const void* memory, size_t size);
374 void SetExternal(StringPiece name,
375 ValueType type,
376 const void* memory,
377 size_t size);
378
379 // TODO(bcwhite): Add Get() methods for Analyzer to use.
380
381 std::map<StringPiece, ValueInfo> values_;
382
383 char* memory_;
384 size_t available_;
385
386 base::ThreadChecker thread_checker_;
387
388 DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
389 };
390
391
287 // This class manages tracking a stack of activities for a single thread in 392 // This class manages tracking a stack of activities for a single thread in
288 // a persistent manner, implementing a bounded-size stack in a fixed-size 393 // a persistent manner, implementing a bounded-size stack in a fixed-size
289 // memory allocation. In order to support an operational mode where another 394 // memory allocation. In order to support an operational mode where another
290 // thread is analyzing this data in real-time, atomic operations are used 395 // thread is analyzing this data in real-time, atomic operations are used
291 // where necessary to guarantee a consistent view from the outside. 396 // where necessary to guarantee a consistent view from the outside.
292 // 397 //
293 // This class is not generally used directly but instead managed by the 398 // This class is not generally used directly but instead managed by the
294 // GlobalActivityTracker instance and updated using Scoped*Activity local 399 // GlobalActivityTracker instance and updated using Scoped*Activity local
295 // objects. 400 // objects.
296 class BASE_EXPORT ThreadActivityTracker { 401 class BASE_EXPORT ThreadActivityTracker {
297 public: 402 public:
403 using ActivityId = uint32_t;
404
298 // This is the base class for having the compiler manage an activity on the 405 // This is the base class for having the compiler manage an activity on the
299 // tracker's stack. It does nothing but call methods on the passed |tracker| 406 // tracker's stack. It does nothing but call methods on the passed |tracker|
300 // if it is not null, making it safe (and cheap) to create these objects 407 // if it is not null, making it safe (and cheap) to create these objects
301 // even if activity tracking is not enabled. 408 // even if activity tracking is not enabled.
302 class BASE_EXPORT ScopedActivity { 409 class BASE_EXPORT ScopedActivity {
303 public: 410 public:
304 ScopedActivity(ThreadActivityTracker* tracker, 411 ScopedActivity(ThreadActivityTracker* tracker,
305 const void* origin, 412 const void* origin,
306 Activity::Type type, 413 Activity::Type type,
307 const ActivityData& data) 414 const ActivityData& data);
308 : tracker_(tracker) { 415 ~ScopedActivity();
309 if (tracker_)
310 tracker_->PushActivity(origin, type, data);
311 }
312 416
313 ~ScopedActivity() { 417 // Changes some basic metadata about the activity.
314 if (tracker_) 418 void ChangeTypeAndData(Activity::Type type, const ActivityData& data);
315 tracker_->PopActivity();
316 }
317 419
318 void ChangeTypeAndData(Activity::Type type, const ActivityData& data) { 420 // Returns an object for manipulating user data.
319 if (tracker_) 421 ActivityUserData& user_data();
320 tracker_->ChangeActivity(type, data);
321 }
322 422
323 private: 423 private:
324 // The thread tracker to which this object reports. It can be null if 424 // The thread tracker to which this object reports. It can be null if
325 // activity tracking is not (yet) enabled. 425 // activity tracking is not (yet) enabled.
326 ThreadActivityTracker* const tracker_; 426 ThreadActivityTracker* const tracker_;
327 427
428 // An identifier that indicates a specific activity on the stack.
429 ActivityId activity_id_;
430
431 // An object that manages additional user data, created only upon request.
432 std::unique_ptr<ActivityUserData> user_data_;
433
328 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); 434 DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
329 }; 435 };
330 436
331 // A ThreadActivityTracker runs on top of memory that is managed externally. 437 // A ThreadActivityTracker runs on top of memory that is managed externally.
332 // It must be large enough for the internal header and a few Activity 438 // It must be large enough for the internal header and a few Activity
333 // blocks. See SizeForStackDepth(). 439 // blocks. See SizeForStackDepth().
334 ThreadActivityTracker(void* base, size_t size); 440 ThreadActivityTracker(void* base, size_t size);
335 virtual ~ThreadActivityTracker(); 441 virtual ~ThreadActivityTracker();
336 442
337 // Indicates that an activity has started from a given |origin| address in 443 // Indicates that an activity has started from a given |origin| address in
338 // the code, though it can be null if the creator's address is not known. 444 // the code, though it can be null if the creator's address is not known.
339 // The |type| and |data| describe the activity. 445 // The |type| and |data| describe the activity. Returned is an ID that can
340 void PushActivity(const void* origin, 446 // be used to adjust the pushed activity.
341 Activity::Type type, 447 ActivityId PushActivity(const void* origin,
342 const ActivityData& data); 448 Activity::Type type,
449 const ActivityData& data);
343 450
344 // Changes the activity |type| and |data| of the top-most entry on the stack. 451 // Changes the activity |type| and |data| of the top-most entry on the stack.
345 // This is useful if the information has changed and it is desireable to 452 // This is useful if the information has changed and it is desireable to
346 // track that change without creating a new stack entry. If the type is 453 // track that change without creating a new stack entry. If the type is
347 // ACT_NULL or the data is kNullActivityData then that value will remain 454 // ACT_NULL or the data is kNullActivityData then that value will remain
348 // unchanged. The type, if changed, must remain in the same category. 455 // unchanged. The type, if changed, must remain in the same category.
349 // Changing both is not atomic so a snapshot operation could occur between 456 // Changing both is not atomic so a snapshot operation could occur between
350 // the update of |type| and |data| or between update of |data| fields. 457 // the update of |type| and |data| or between update of |data| fields.
351 void ChangeActivity(Activity::Type type, const ActivityData& data); 458 void ChangeActivity(ActivityId id,
459 Activity::Type type,
460 const ActivityData& data);
352 461
353 // Indicates that an activity has completed. 462 // Indicates that an activity has completed.
354 void PopActivity(); 463 void PopActivity(ActivityId id);
464
465 // Returns an object capable of storing arbitrary user data.
466 std::unique_ptr<ActivityUserData> GetUserData(ActivityId id);
355 467
356 // Returns whether the current data is valid or not. It is not valid if 468 // Returns whether the current data is valid or not. It is not valid if
357 // corruption has been detected in the header or other data structures. 469 // corruption has been detected in the header or other data structures.
358 bool IsValid() const; 470 bool IsValid() const;
359 471
360 // Gets a copy of the tracker contents for analysis. Returns false if a 472 // Gets a copy of the tracker contents for analysis. Returns false if a
361 // snapshot was not possible, perhaps because the data is not valid; the 473 // snapshot was not possible, perhaps because the data is not valid; the
362 // contents of |output_snapshot| are undefined in that case. The current 474 // contents of |output_snapshot| are undefined in that case. The current
363 // implementation does not support concurrent snapshot operations. 475 // implementation does not support concurrent snapshot operations.
364 bool Snapshot(ActivitySnapshot* output_snapshot) const; 476 bool Snapshot(ActivitySnapshot* output_snapshot) const;
(...skipping 27 matching lines...) Expand all
392 // for the data to be analyzed by a parallel process or even post-mortem. 504 // for the data to be analyzed by a parallel process or even post-mortem.
393 class BASE_EXPORT GlobalActivityTracker { 505 class BASE_EXPORT GlobalActivityTracker {
394 public: 506 public:
395 // Type identifiers used when storing in persistent memory so they can be 507 // Type identifiers used when storing in persistent memory so they can be
396 // identified during extraction; the first 4 bytes of the SHA1 of the name 508 // identified during extraction; the first 4 bytes of the SHA1 of the name
397 // is used as a unique integer. A "version number" is added to the base 509 // is used as a unique integer. A "version number" is added to the base
398 // so that, if the structure of that object changes, stored older versions 510 // so that, if the structure of that object changes, stored older versions
399 // will be safely ignored. These are public so that an external process 511 // will be safely ignored. These are public so that an external process
400 // can recognize records of this type within an allocator. 512 // can recognize records of this type within an allocator.
401 enum : uint32_t { 513 enum : uint32_t {
402 kTypeIdActivityTracker = 0x5D7381AF + 1, // SHA1(ActivityTracker) v1 514 kTypeIdActivityTracker = 0x5D7381AF + 2, // SHA1(ActivityTracker) v2
515 kTypeIdUserDataRecord = 0x615EDDD7 + 1, // SHA1(UserDataRecord) v1
516 kTypeIdGlobalDataRecord = 0xAFE61ABE + 1, // SHA1(GlobalDataRecord) v1
517
403 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, 518 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
519 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
404 }; 520 };
405 521
406 // This is a thin wrapper around the thread-tracker's ScopedActivity that 522 // This is a thin wrapper around the thread-tracker's ScopedActivity that
407 // accesses the global tracker to provide some of the information, notably 523 // accesses the global tracker to provide some of the information, notably
408 // which thread-tracker to use. It is safe to create even if activity 524 // which thread-tracker to use. It is safe to create even if activity
409 // tracking is not enabled. 525 // tracking is not enabled.
410 class BASE_EXPORT ScopedThreadActivity 526 class BASE_EXPORT ScopedThreadActivity
411 : public ThreadActivityTracker::ScopedActivity { 527 : public ThreadActivityTracker::ScopedActivity {
412 public: 528 public:
413 ScopedThreadActivity(const void* origin, 529 ScopedThreadActivity(const void* origin,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 return tracker; 608 return tracker;
493 return CreateTrackerForCurrentThread(); 609 return CreateTrackerForCurrentThread();
494 } 610 }
495 611
496 // Creates an activity-tracker for the current thread. 612 // Creates an activity-tracker for the current thread.
497 ThreadActivityTracker* CreateTrackerForCurrentThread(); 613 ThreadActivityTracker* CreateTrackerForCurrentThread();
498 614
499 // Releases the activity-tracker for the current thread (for testing only). 615 // Releases the activity-tracker for the current thread (for testing only).
500 void ReleaseTrackerForCurrentThreadForTesting(); 616 void ReleaseTrackerForCurrentThreadForTesting();
501 617
618 // Gets a reference to memory for holding user-defined activity data. If
619 // the reference is valid, it's memory will be returned. If not, then a
620 // new reference will be created (and stored) and that memory returned.
621 void* GetUserDataMemory(PersistentMemoryAllocator::Reference* reference);
622
623 // Releases memory for user-defined activity data.
624 void ReleaseUserDataMemory(PersistentMemoryAllocator::Reference* reference);
625
626 // Accesses the global data record for storing arbitrary key/value pairs.
627 ActivityUserData& user_data() { return user_data_; }
628
502 private: 629 private:
503 friend class ActivityTrackerTest; 630 friend class ActivityTrackerTest;
504 631
505 enum : int { 632 enum : int {
506 // The maximum number of threads that can be tracked within a process. If 633 // The maximum number of threads that can be tracked within a process. If
507 // more than this number run concurrently, tracking of new ones may cease. 634 // more than this number run concurrently, tracking of new ones may cease.
508 kMaxThreadCount = 100, 635 kMaxThreadCount = 100,
509 kCachedThreadMemories = 10, 636 kCachedThreadMemories = 10,
637 kCachedUserDataMemories = 10,
510 }; 638 };
511 639
512 // A thin wrapper around the main thread-tracker that keeps additional 640 // A thin wrapper around the main thread-tracker that keeps additional
513 // information that the global tracker needs to handle joined threads. 641 // information that the global tracker needs to handle joined threads.
514 class ManagedActivityTracker : public ThreadActivityTracker { 642 class ManagedActivityTracker : public ThreadActivityTracker {
515 public: 643 public:
516 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 644 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
517 void* base, 645 void* base,
518 size_t size); 646 size_t size);
519 ~ManagedActivityTracker() override; 647 ~ManagedActivityTracker() override;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 // The activity tracker for the currently executing thread. 683 // The activity tracker for the currently executing thread.
556 base::ThreadLocalStorage::Slot this_thread_tracker_; 684 base::ThreadLocalStorage::Slot this_thread_tracker_;
557 685
558 // The number of thread trackers currently active. 686 // The number of thread trackers currently active.
559 std::atomic<int> thread_tracker_count_; 687 std::atomic<int> thread_tracker_count_;
560 688
561 // A caching memory allocator for thread-tracker objects. 689 // A caching memory allocator for thread-tracker objects.
562 ActivityTrackerMemoryAllocator thread_tracker_allocator_; 690 ActivityTrackerMemoryAllocator thread_tracker_allocator_;
563 base::Lock thread_tracker_allocator_lock_; 691 base::Lock thread_tracker_allocator_lock_;
564 692
693 // A caching memory allocator for user data attached to activity data.
694 ActivityTrackerMemoryAllocator user_data_allocator_;
695 base::Lock user_data_allocator_lock_;
696
697 // An object for holding global arbitrary key value pairs.
698 ActivityUserData user_data_;
manzagop (departed) 2016/11/11 17:01:42 This has a thread checker, so it should only be us
bcwhite 2016/11/14 15:08:43 Done.
699
565 // The active global activity tracker. 700 // The active global activity tracker.
566 static GlobalActivityTracker* g_tracker_; 701 static GlobalActivityTracker* g_tracker_;
567 702
568 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 703 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
569 }; 704 };
570 705
571 706
572 // Record entry in to and out of an arbitrary block of code. 707 // Record entry in to and out of an arbitrary block of code.
573 class BASE_EXPORT ScopedActivity 708 class BASE_EXPORT ScopedActivity
574 : public GlobalActivityTracker::ScopedThreadActivity { 709 : public GlobalActivityTracker::ScopedThreadActivity {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 explicit ScopedProcessWaitActivity(const base::Process* process); 792 explicit ScopedProcessWaitActivity(const base::Process* process);
658 private: 793 private:
659 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 794 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
660 }; 795 };
661 #endif 796 #endif
662 797
663 } // namespace debug 798 } // namespace debug
664 } // namespace base 799 } // namespace base
665 800
666 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 801 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698