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

Unified Diff: base/debug/activity_tracker.h

Issue 2235273002: Refactor embedded structures to top-level scope. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: removed new ResourceData class (for later CL) Created 4 years, 4 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/debug/activity_tracker.h
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h
index acac6b14e7b26103c66b31a9b67a3251206c5815..d6ff724cf2daee6106c3fbce75b9622f1d7a9eda 100644
--- a/base/debug/activity_tracker.h
+++ b/base/debug/activity_tracker.h
@@ -39,29 +39,100 @@ class WaitableEvent;
namespace debug {
-// This class manages tracking a stack of activities for a single thread in
-// a persistent manner, implementing a bounded-size stack in a fixed-size
-// memory allocation. In order to support an operational mode where another
-// thread is analyzing this data in real-time, atomic operations are used
-// where necessary to guarantee a consistent view from the outside.
-//
-// This class is not generally used directly but instead managed by the
-// GlobalActivityTracker instance and updated using Scoped*Activity local
-// objects.
-class BASE_EXPORT ThreadActivityTracker {
- public:
- enum : int {
- // The maximum number of call-stack addresses stored per activity. This
- // cannot be changed without also changing the version number of the
- // structure. See kTypeIdActivityTracker in GlobalActivityTracker.
- kActivityCallStackSize = 10
- };
+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
+ // structure. See kTypeIdActivityTracker in GlobalActivityTracker.
+ kActivityCallStackSize = 10,
+};
+
+// The data associated with an activity is dependent upon the activity type.
+// This union defines all of the various fields. All fields must be explicitly
+// sized types to ensure no interoperability problems between 32-bit and
+// 64-bit systems.
+union ActivityData {
+ // Generic activities don't have any defined structure.
+ struct {
+ uint32_t id; // An arbitrary identifier used for association.
+ int32_t info; // An arbitrary value used for information purposes.
+ } generic;
+ struct {
+ uint64_t sequence_id; // The sequence identifier of the posted task.
+ } task;
+ struct {
+ uint64_t lock_address; // The memory address of the lock object.
+ } lock;
+ struct {
+ uint64_t event_address; // The memory address of the event object.
+ } event;
+ struct {
+ int64_t thread_id; // A unique identifier for a thread within a process.
+ } thread;
+ struct {
+ int64_t process_id; // A unique identifier for a process.
+ } process;
+
+ // These methods create an ActivityData object from the appropriate
+ // parameters. Objects of this type should always be created this way to
+ // ensure that no fields remain unpopulated should the set of recorded
+ // fields change. They're defined inline where practical because they
+ // reduce to loading a small local structure with a few values, roughly
+ // the same as loading all those values into parameters.
+
+ static ActivityData ForGeneric(uint32_t id, int32_t info) {
+ ActivityData data;
+ data.generic.id = id;
+ data.generic.info = info;
+ return data;
+ }
+
+ static ActivityData ForTask(uint64_t sequence) {
+ ActivityData data;
+ data.task.sequence_id = sequence;
+ return data;
+ }
+
+ static ActivityData ForLock(const void* lock) {
+ ActivityData data;
+ data.lock.lock_address = reinterpret_cast<uintptr_t>(lock);
+ return data;
+ }
+
+ static ActivityData ForEvent(const void* event) {
+ ActivityData data;
+ data.event.event_address = reinterpret_cast<uintptr_t>(event);
+ return data;
+ }
+
+ static ActivityData ForThread(const PlatformThreadHandle& handle);
+ static ActivityData ForThread(const int64_t id) {
+ ActivityData data;
+ data.thread.thread_id = id;
+ return data;
+ }
+
+ static ActivityData ForProcess(const int64_t id) {
+ ActivityData data;
+ data.process.process_id = id;
+ return data;
+ }
+};
+// A "null" activity-data that can be passed to indicate "do not change".
+extern const ActivityData kNullActivityData;
+
+// This structure is the full contents recorded for every activity pushed
+// onto the stack. The |activity_type| indicates what is actually stored in
+// the |data| field. All fields must be explicitly sized types to ensure no
+// interoperability problems between 32-bit and 64-bit systems.
+struct Activity {
// The type of an activity on the stack. Activities are broken into
// categories with the category ID taking the top 4 bits and the lower
// bits representing an action within that category. This combination
// makes it easy to "switch" based on the type during analysis.
- enum ActivityType : uint8_t {
+ enum Type : uint8_t {
// This "null" constant is used to indicate "do not change" in calls.
ACT_NULL = 0,
@@ -99,142 +170,82 @@ class BASE_EXPORT ThreadActivityTracker {
ACT_ACTION_MASK = 0xF
};
- // The data associated with an activity is dependent upon the activity type.
- // This union defines all of the various fields. All fields must be explicitly
- // sized types to ensure no interoperability problems between 32-bit and
- // 64-bit systems.
- union ActivityData {
- // Generic activities don't have any defined structure.
- struct {
- uint32_t id; // An arbitrary identifier used for association.
- int32_t info; // An arbitrary value used for information purposes.
- } generic;
- struct {
- uint64_t sequence_id; // The sequence identifier of the posted task.
- } task;
- struct {
- uint64_t lock_address; // The memory address of the lock object.
- } lock;
- struct {
- uint64_t event_address; // The memory address of the event object.
- } event;
- struct {
- int64_t thread_id; // A unique identifier for a thread within a process.
- } thread;
- struct {
- int64_t process_id; // A unique identifier for a process.
- } process;
-
- // These methods create an ActivityData object from the appropriate
- // parameters. Objects of this type should always be created this way to
- // ensure that no fields remain unpopulated should the set of recorded
- // fields change. They're defined inline where practical because they
- // reduce to loading a small local structure with a few values, roughly
- // the same as loading all those values into parameters.
-
- static ActivityData ForGeneric(uint32_t id, int32_t info) {
- ActivityData data;
- data.generic.id = id;
- data.generic.info = info;
- return data;
- }
-
- static ActivityData ForTask(uint64_t sequence) {
- ActivityData data;
- data.task.sequence_id = sequence;
- return data;
- }
-
- static ActivityData ForLock(const void* lock) {
- ActivityData data;
- data.lock.lock_address = reinterpret_cast<uintptr_t>(lock);
- return data;
- }
-
- static ActivityData ForEvent(const void* event) {
- ActivityData data;
- data.event.event_address = reinterpret_cast<uintptr_t>(event);
- return data;
- }
-
- static ActivityData ForThread(const PlatformThreadHandle& handle);
- static ActivityData ForThread(const int64_t id) {
- ActivityData data;
- data.thread.thread_id = id;
- return data;
- }
-
- static ActivityData ForProcess(const int64_t id) {
- ActivityData data;
- data.process.process_id = id;
- return data;
- }
- };
+ // Internal representation of time. During collection, this is in "ticks"
+ // but when returned in a snapshot, it is "wall time".
+ int64_t time_internal;
+
+ // The address that is the origin of the activity if it not obvious from
+ // the call stack. This is useful for things like tasks that are posted
+ // from a completely different thread though most activities will leave
+ // it null.
+ uint64_t origin_address;
+
+ // Array of program-counters that make up the top of the call stack.
+ // Despite the fixed size, this list is always null-terminated. Entries
+ // after the terminator have no meaning and may or may not also be null.
+ // The list will be completely empty if call-stack collection is not
+ // enabled.
+ uint64_t call_stack[kActivityCallStackSize];
+
+ // The (enumerated) type of the activity. This defines what fields of the
+ // |data| record are valid.
+ uint8_t activity_type;
+
+ // Padding to ensure that the next member begins on a 64-bit boundary
+ // even on 32-bit builds which ensures inter-operability between CPU
+ // architectures. New fields can be taken from this space.
+ uint8_t padding[7];
+
+ // Information specific to the |activity_type|.
+ ActivityData data;
+
+ static void FillFrom(Activity* activity,
+ const void* origin,
+ Type type,
+ const ActivityData& data);
+};
- // This structure is the full contents recorded for every activity pushed
- // onto the stack. The |activity_type| indicates what is actually stored in
- // the |data| field. All fields must be explicitly sized types to ensure no
- // interoperability problems between 32-bit and 64-bit systems.
- struct Activity {
- // Internal representation of time. During collection, this is in "ticks"
- // but when returned in a snapshot, it is "wall time".
- int64_t time_internal;
-
- // The address that is the origin of the activity if it not obvious from
- // the call stack. This is useful for things like tasks that are posted
- // from a completely different thread though most activities will leave
- // it null.
- uint64_t origin_address;
-
- // Array of program-counters that make up the top of the call stack.
- // Despite the fixed size, this list is always null-terminated. Entries
- // after the terminator have no meaning and may or may not also be null.
- // The list will be completely empty if call-stack collection is not
- // enabled.
- uint64_t call_stack[kActivityCallStackSize];
-
- // The (enumerated) type of the activity. This defines what fields of the
- // |data| record are valid.
- uint8_t activity_type;
-
- // Padding to ensure that the next member begins on a 64-bit boundary
- // even on 32-bit builds which ensures inter-operability between CPU
- // architectures. New fields can be taken from this space.
- uint8_t padding[7];
-
- // Information specific to the |activity_type|.
- ActivityData data;
- };
+// This structure holds a copy of all the internal data at the moment the
+// "snapshot" operation is done. It is disconnected from the live tracker
+// so that continued operation of the thread will not cause changes here.
+struct BASE_EXPORT ActivitySnapshot {
+ // Explicit constructor/destructor are needed because of complex types
+ // with non-trivial default constructors and destructors.
+ ActivitySnapshot();
+ ~ActivitySnapshot();
+
+ // The name of the thread as set when it was created. The name may be
+ // truncated due to internal length limitations.
+ std::string thread_name;
+
+ // The process and thread IDs. These values have no meaning other than
+ // they uniquely identify a running process and a running thread within
+ // that process. Thread-IDs can be re-used across different processes
+ // and both can be re-used after the process/thread exits.
+ int64_t process_id = 0;
+ int64_t thread_id = 0;
+
+ // The current stack of activities that are underway for this thread. It
+ // is limited in its maximum size with later entries being left off.
+ std::vector<Activity> activity_stack;
+
+ // The current total depth of the activity stack, including those later
+ // entries not recorded in the |activity_stack| vector.
+ uint32_t activity_stack_depth = 0;
+};
- // This structure holds a copy of all the internal data at the moment the
- // "snapshot" operation is done. It is disconnected from the live tracker
- // so that continued operation of the thread will not cause changes here.
- struct BASE_EXPORT ActivitySnapshot {
- // Explicit constructor/destructor are needed because of complex types
- // with non-trivial default constructors and destructors.
- ActivitySnapshot();
- ~ActivitySnapshot();
-
- // The name of the thread as set when it was created. The name may be
- // truncated due to internal length limitations.
- std::string thread_name;
-
- // The process and thread IDs. These values have no meaning other than
- // they uniquely identify a running process and a running thread within
- // that process. Thread-IDs can be re-used across different processes
- // and both can be re-used after the process/thread exits.
- int64_t process_id = 0;
- int64_t thread_id = 0;
-
- // The current stack of activities that are underway for this thread. It
- // is limited in its maximum size with later entries being left off.
- std::vector<Activity> activity_stack;
-
- // The current total depth of the activity stack, including those later
- // entries not recorded in the |activity_stack| vector.
- uint32_t activity_stack_depth = 0;
- };
+// This class manages tracking a stack of activities for a single thread in
+// a persistent manner, implementing a bounded-size stack in a fixed-size
+// memory allocation. In order to support an operational mode where another
+// thread is analyzing this data in real-time, atomic operations are used
+// where necessary to guarantee a consistent view from the outside.
+//
+// This class is not generally used directly but instead managed by the
+// GlobalActivityTracker instance and updated using Scoped*Activity local
+// objects.
+class BASE_EXPORT ThreadActivityTracker {
+ public:
// This is the base class for having the compiler manage an activity on the
// tracker's stack. It does nothing but call methods on the passed |tracker|
// if it is not null, making it safe (and cheap) to create these objects
@@ -243,7 +254,7 @@ class BASE_EXPORT ThreadActivityTracker {
public:
ScopedActivity(ThreadActivityTracker* tracker,
const void* origin,
- ActivityType type,
+ Activity::Type type,
const ActivityData& data)
: tracker_(tracker) {
if (tracker_)
@@ -255,7 +266,7 @@ class BASE_EXPORT ThreadActivityTracker {
tracker_->PopActivity();
}
- void ChangeTypeAndData(ActivityType type, const ActivityData& data) {
+ void ChangeTypeAndData(Activity::Type type, const ActivityData& data) {
if (tracker_)
tracker_->ChangeActivity(type, data);
}
@@ -278,7 +289,7 @@ class BASE_EXPORT ThreadActivityTracker {
// the code, though it can be null if the creator's address is not known.
// The |type| and |data| describe the activity.
void PushActivity(const void* origin,
- ActivityType type,
+ Activity::Type type,
const ActivityData& data);
// Changes the activity |type| and |data| of the top-most entry on the stack.
@@ -288,7 +299,7 @@ class BASE_EXPORT ThreadActivityTracker {
// unchanged. The type, if changed, must remain in the same category.
// Changing both is not atomic so a snapshot operation could occur between
// the update of |type| and |data| or between update of |data| fields.
- void ChangeActivity(ActivityType type, const ActivityData& data);
+ void ChangeActivity(Activity::Type type, const ActivityData& data);
// Indicates that an activity has completed.
void PopActivity();
@@ -307,9 +318,6 @@ class BASE_EXPORT ThreadActivityTracker {
// the internal header structure for the stack.
static size_t SizeForStackDepth(int stack_depth);
- // A "null" activity-data that can be passed to indicate "do not change".
- static const ActivityData kNullActivityData;
-
private:
friend class ActivityTrackerTest;
@@ -354,8 +362,8 @@ class BASE_EXPORT GlobalActivityTracker {
: public ThreadActivityTracker::ScopedActivity {
public:
ScopedThreadActivity(const void* origin,
- ThreadActivityTracker::ActivityType type,
- const ThreadActivityTracker::ActivityData& data,
+ Activity::Type type,
+ const ActivityData& data,
bool lock_allowed)
: ThreadActivityTracker::ScopedActivity(
GetOrCreateTracker(lock_allowed),
« 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