| OLD | NEW |
| 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 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 class FilePath; | 33 class FilePath; |
| 34 class Lock; | 34 class Lock; |
| 35 class MemoryMappedFile; | 35 class MemoryMappedFile; |
| 36 class PlatformThreadHandle; | 36 class PlatformThreadHandle; |
| 37 class Process; | 37 class Process; |
| 38 class WaitableEvent; | 38 class WaitableEvent; |
| 39 | 39 |
| 40 namespace debug { | 40 namespace debug { |
| 41 | 41 |
| 42 // This class manages tracking a stack of activities for a single thread in | 42 class ThreadActivityTracker; |
| 43 // a persistent manner, implementing a bounded-size stack in a fixed-size | |
| 44 // memory allocation. In order to support an operational mode where another | |
| 45 // thread is analyzing this data in real-time, atomic operations are used | |
| 46 // where necessary to guarantee a consistent view from the outside. | |
| 47 // | |
| 48 // This class is not generally used directly but instead managed by the | |
| 49 // GlobalActivityTracker instance and updated using Scoped*Activity local | |
| 50 // objects. | |
| 51 class BASE_EXPORT ThreadActivityTracker { | |
| 52 public: | |
| 53 enum : int { | |
| 54 // The maximum number of call-stack addresses stored per activity. This | |
| 55 // cannot be changed without also changing the version number of the | |
| 56 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. | |
| 57 kActivityCallStackSize = 10 | |
| 58 }; | |
| 59 | 43 |
| 44 enum : int { |
| 45 // The maximum number of call-stack addresses stored per activity. This |
| 46 // cannot be changed without also changing the version number of the |
| 47 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. |
| 48 kActivityCallStackSize = 10, |
| 49 }; |
| 50 |
| 51 // The data associated with an activity is dependent upon the activity type. |
| 52 // This union defines all of the various fields. All fields must be explicitly |
| 53 // sized types to ensure no interoperability problems between 32-bit and |
| 54 // 64-bit systems. |
| 55 union ActivityData { |
| 56 // Generic activities don't have any defined structure. |
| 57 struct { |
| 58 uint32_t id; // An arbitrary identifier used for association. |
| 59 int32_t info; // An arbitrary value used for information purposes. |
| 60 } generic; |
| 61 struct { |
| 62 uint64_t sequence_id; // The sequence identifier of the posted task. |
| 63 } task; |
| 64 struct { |
| 65 uint64_t lock_address; // The memory address of the lock object. |
| 66 } lock; |
| 67 struct { |
| 68 uint64_t event_address; // The memory address of the event object. |
| 69 } event; |
| 70 struct { |
| 71 int64_t thread_id; // A unique identifier for a thread within a process. |
| 72 } thread; |
| 73 struct { |
| 74 int64_t process_id; // A unique identifier for a process. |
| 75 } process; |
| 76 |
| 77 // These methods create an ActivityData object from the appropriate |
| 78 // parameters. Objects of this type should always be created this way to |
| 79 // ensure that no fields remain unpopulated should the set of recorded |
| 80 // fields change. They're defined inline where practical because they |
| 81 // reduce to loading a small local structure with a few values, roughly |
| 82 // the same as loading all those values into parameters. |
| 83 |
| 84 static ActivityData ForGeneric(uint32_t id, int32_t info) { |
| 85 ActivityData data; |
| 86 data.generic.id = id; |
| 87 data.generic.info = info; |
| 88 return data; |
| 89 } |
| 90 |
| 91 static ActivityData ForTask(uint64_t sequence) { |
| 92 ActivityData data; |
| 93 data.task.sequence_id = sequence; |
| 94 return data; |
| 95 } |
| 96 |
| 97 static ActivityData ForLock(const void* lock) { |
| 98 ActivityData data; |
| 99 data.lock.lock_address = reinterpret_cast<uintptr_t>(lock); |
| 100 return data; |
| 101 } |
| 102 |
| 103 static ActivityData ForEvent(const void* event) { |
| 104 ActivityData data; |
| 105 data.event.event_address = reinterpret_cast<uintptr_t>(event); |
| 106 return data; |
| 107 } |
| 108 |
| 109 static ActivityData ForThread(const PlatformThreadHandle& handle); |
| 110 static ActivityData ForThread(const int64_t id) { |
| 111 ActivityData data; |
| 112 data.thread.thread_id = id; |
| 113 return data; |
| 114 } |
| 115 |
| 116 static ActivityData ForProcess(const int64_t id) { |
| 117 ActivityData data; |
| 118 data.process.process_id = id; |
| 119 return data; |
| 120 } |
| 121 }; |
| 122 |
| 123 // A "null" activity-data that can be passed to indicate "do not change". |
| 124 extern const ActivityData kNullActivityData; |
| 125 |
| 126 // This structure is the full contents recorded for every activity pushed |
| 127 // onto the stack. The |activity_type| indicates what is actually stored in |
| 128 // the |data| field. All fields must be explicitly sized types to ensure no |
| 129 // interoperability problems between 32-bit and 64-bit systems. |
| 130 struct Activity { |
| 60 // The type of an activity on the stack. Activities are broken into | 131 // The type of an activity on the stack. Activities are broken into |
| 61 // categories with the category ID taking the top 4 bits and the lower | 132 // categories with the category ID taking the top 4 bits and the lower |
| 62 // bits representing an action within that category. This combination | 133 // bits representing an action within that category. This combination |
| 63 // makes it easy to "switch" based on the type during analysis. | 134 // makes it easy to "switch" based on the type during analysis. |
| 64 enum ActivityType : uint8_t { | 135 enum Type : uint8_t { |
| 65 // This "null" constant is used to indicate "do not change" in calls. | 136 // This "null" constant is used to indicate "do not change" in calls. |
| 66 ACT_NULL = 0, | 137 ACT_NULL = 0, |
| 67 | 138 |
| 68 // Task activities involve callbacks posted to a thread or thread-pool | 139 // Task activities involve callbacks posted to a thread or thread-pool |
| 69 // using the PostTask() method or any of its friends. | 140 // using the PostTask() method or any of its friends. |
| 70 ACT_TASK = 1 << 4, | 141 ACT_TASK = 1 << 4, |
| 71 ACT_TASK_RUN = ACT_TASK, | 142 ACT_TASK_RUN = ACT_TASK, |
| 72 | 143 |
| 73 // Lock activities involve the acquisition of "mutex" locks. | 144 // Lock activities involve the acquisition of "mutex" locks. |
| 74 ACT_LOCK = 2 << 4, | 145 ACT_LOCK = 2 << 4, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 92 | 163 |
| 93 // Generic activities are user defined and can be anything. | 164 // Generic activities are user defined and can be anything. |
| 94 ACT_GENERIC = 15 << 4, | 165 ACT_GENERIC = 15 << 4, |
| 95 | 166 |
| 96 // These constants can be used to separate the category and action from | 167 // These constants can be used to separate the category and action from |
| 97 // a combined activity type. | 168 // a combined activity type. |
| 98 ACT_CATEGORY_MASK = 0xF << 4, | 169 ACT_CATEGORY_MASK = 0xF << 4, |
| 99 ACT_ACTION_MASK = 0xF | 170 ACT_ACTION_MASK = 0xF |
| 100 }; | 171 }; |
| 101 | 172 |
| 102 // The data associated with an activity is dependent upon the activity type. | 173 // Internal representation of time. During collection, this is in "ticks" |
| 103 // This union defines all of the various fields. All fields must be explicitly | 174 // but when returned in a snapshot, it is "wall time". |
| 104 // sized types to ensure no interoperability problems between 32-bit and | 175 int64_t time_internal; |
| 105 // 64-bit systems. | |
| 106 union ActivityData { | |
| 107 // Generic activities don't have any defined structure. | |
| 108 struct { | |
| 109 uint32_t id; // An arbitrary identifier used for association. | |
| 110 int32_t info; // An arbitrary value used for information purposes. | |
| 111 } generic; | |
| 112 struct { | |
| 113 uint64_t sequence_id; // The sequence identifier of the posted task. | |
| 114 } task; | |
| 115 struct { | |
| 116 uint64_t lock_address; // The memory address of the lock object. | |
| 117 } lock; | |
| 118 struct { | |
| 119 uint64_t event_address; // The memory address of the event object. | |
| 120 } event; | |
| 121 struct { | |
| 122 int64_t thread_id; // A unique identifier for a thread within a process. | |
| 123 } thread; | |
| 124 struct { | |
| 125 int64_t process_id; // A unique identifier for a process. | |
| 126 } process; | |
| 127 | 176 |
| 128 // These methods create an ActivityData object from the appropriate | 177 // The address that is the origin of the activity if it not obvious from |
| 129 // parameters. Objects of this type should always be created this way to | 178 // the call stack. This is useful for things like tasks that are posted |
| 130 // ensure that no fields remain unpopulated should the set of recorded | 179 // from a completely different thread though most activities will leave |
| 131 // fields change. They're defined inline where practical because they | 180 // it null. |
| 132 // reduce to loading a small local structure with a few values, roughly | 181 uint64_t origin_address; |
| 133 // the same as loading all those values into parameters. | |
| 134 | 182 |
| 135 static ActivityData ForGeneric(uint32_t id, int32_t info) { | 183 // Array of program-counters that make up the top of the call stack. |
| 136 ActivityData data; | 184 // Despite the fixed size, this list is always null-terminated. Entries |
| 137 data.generic.id = id; | 185 // after the terminator have no meaning and may or may not also be null. |
| 138 data.generic.info = info; | 186 // The list will be completely empty if call-stack collection is not |
| 139 return data; | 187 // enabled. |
| 140 } | 188 uint64_t call_stack[kActivityCallStackSize]; |
| 141 | 189 |
| 142 static ActivityData ForTask(uint64_t sequence) { | 190 // The (enumerated) type of the activity. This defines what fields of the |
| 143 ActivityData data; | 191 // |data| record are valid. |
| 144 data.task.sequence_id = sequence; | 192 uint8_t activity_type; |
| 145 return data; | |
| 146 } | |
| 147 | 193 |
| 148 static ActivityData ForLock(const void* lock) { | 194 // Padding to ensure that the next member begins on a 64-bit boundary |
| 149 ActivityData data; | 195 // even on 32-bit builds which ensures inter-operability between CPU |
| 150 data.lock.lock_address = reinterpret_cast<uintptr_t>(lock); | 196 // architectures. New fields can be taken from this space. |
| 151 return data; | 197 uint8_t padding[7]; |
| 152 } | |
| 153 | 198 |
| 154 static ActivityData ForEvent(const void* event) { | 199 // Information specific to the |activity_type|. |
| 155 ActivityData data; | 200 ActivityData data; |
| 156 data.event.event_address = reinterpret_cast<uintptr_t>(event); | |
| 157 return data; | |
| 158 } | |
| 159 | 201 |
| 160 static ActivityData ForThread(const PlatformThreadHandle& handle); | 202 static void FillFrom(Activity* activity, |
| 161 static ActivityData ForThread(const int64_t id) { | 203 const void* origin, |
| 162 ActivityData data; | 204 Type type, |
| 163 data.thread.thread_id = id; | 205 const ActivityData& data); |
| 164 return data; | 206 }; |
| 165 } | |
| 166 | 207 |
| 167 static ActivityData ForProcess(const int64_t id) { | 208 // This structure holds a copy of all the internal data at the moment the |
| 168 ActivityData data; | 209 // "snapshot" operation is done. It is disconnected from the live tracker |
| 169 data.process.process_id = id; | 210 // so that continued operation of the thread will not cause changes here. |
| 170 return data; | 211 struct BASE_EXPORT ActivitySnapshot { |
| 171 } | 212 // Explicit constructor/destructor are needed because of complex types |
| 172 }; | 213 // with non-trivial default constructors and destructors. |
| 214 ActivitySnapshot(); |
| 215 ~ActivitySnapshot(); |
| 173 | 216 |
| 174 // This structure is the full contents recorded for every activity pushed | 217 // The name of the thread as set when it was created. The name may be |
| 175 // onto the stack. The |activity_type| indicates what is actually stored in | 218 // truncated due to internal length limitations. |
| 176 // the |data| field. All fields must be explicitly sized types to ensure no | 219 std::string thread_name; |
| 177 // interoperability problems between 32-bit and 64-bit systems. | |
| 178 struct Activity { | |
| 179 // Internal representation of time. During collection, this is in "ticks" | |
| 180 // but when returned in a snapshot, it is "wall time". | |
| 181 int64_t time_internal; | |
| 182 | 220 |
| 183 // The address that is the origin of the activity if it not obvious from | 221 // The process and thread IDs. These values have no meaning other than |
| 184 // the call stack. This is useful for things like tasks that are posted | 222 // they uniquely identify a running process and a running thread within |
| 185 // from a completely different thread though most activities will leave | 223 // that process. Thread-IDs can be re-used across different processes |
| 186 // it null. | 224 // and both can be re-used after the process/thread exits. |
| 187 uint64_t origin_address; | 225 int64_t process_id = 0; |
| 226 int64_t thread_id = 0; |
| 188 | 227 |
| 189 // Array of program-counters that make up the top of the call stack. | 228 // The current stack of activities that are underway for this thread. It |
| 190 // Despite the fixed size, this list is always null-terminated. Entries | 229 // is limited in its maximum size with later entries being left off. |
| 191 // after the terminator have no meaning and may or may not also be null. | 230 std::vector<Activity> activity_stack; |
| 192 // The list will be completely empty if call-stack collection is not | |
| 193 // enabled. | |
| 194 uint64_t call_stack[kActivityCallStackSize]; | |
| 195 | 231 |
| 196 // The (enumerated) type of the activity. This defines what fields of the | 232 // The current total depth of the activity stack, including those later |
| 197 // |data| record are valid. | 233 // entries not recorded in the |activity_stack| vector. |
| 198 uint8_t activity_type; | 234 uint32_t activity_stack_depth = 0; |
| 235 }; |
| 199 | 236 |
| 200 // Padding to ensure that the next member begins on a 64-bit boundary | |
| 201 // even on 32-bit builds which ensures inter-operability between CPU | |
| 202 // architectures. New fields can be taken from this space. | |
| 203 uint8_t padding[7]; | |
| 204 | 237 |
| 205 // Information specific to the |activity_type|. | 238 // This class manages tracking a stack of activities for a single thread in |
| 206 ActivityData data; | 239 // a persistent manner, implementing a bounded-size stack in a fixed-size |
| 207 }; | 240 // memory allocation. In order to support an operational mode where another |
| 208 | 241 // thread is analyzing this data in real-time, atomic operations are used |
| 209 // This structure holds a copy of all the internal data at the moment the | 242 // where necessary to guarantee a consistent view from the outside. |
| 210 // "snapshot" operation is done. It is disconnected from the live tracker | 243 // |
| 211 // so that continued operation of the thread will not cause changes here. | 244 // This class is not generally used directly but instead managed by the |
| 212 struct BASE_EXPORT ActivitySnapshot { | 245 // GlobalActivityTracker instance and updated using Scoped*Activity local |
| 213 // Explicit constructor/destructor are needed because of complex types | 246 // objects. |
| 214 // with non-trivial default constructors and destructors. | 247 class BASE_EXPORT ThreadActivityTracker { |
| 215 ActivitySnapshot(); | 248 public: |
| 216 ~ActivitySnapshot(); | |
| 217 | |
| 218 // The name of the thread as set when it was created. The name may be | |
| 219 // truncated due to internal length limitations. | |
| 220 std::string thread_name; | |
| 221 | |
| 222 // The process and thread IDs. These values have no meaning other than | |
| 223 // they uniquely identify a running process and a running thread within | |
| 224 // that process. Thread-IDs can be re-used across different processes | |
| 225 // and both can be re-used after the process/thread exits. | |
| 226 int64_t process_id = 0; | |
| 227 int64_t thread_id = 0; | |
| 228 | |
| 229 // The current stack of activities that are underway for this thread. It | |
| 230 // is limited in its maximum size with later entries being left off. | |
| 231 std::vector<Activity> activity_stack; | |
| 232 | |
| 233 // The current total depth of the activity stack, including those later | |
| 234 // entries not recorded in the |activity_stack| vector. | |
| 235 uint32_t activity_stack_depth = 0; | |
| 236 }; | |
| 237 | |
| 238 // This is the base class for having the compiler manage an activity on the | 249 // This is the base class for having the compiler manage an activity on the |
| 239 // tracker's stack. It does nothing but call methods on the passed |tracker| | 250 // tracker's stack. It does nothing but call methods on the passed |tracker| |
| 240 // if it is not null, making it safe (and cheap) to create these objects | 251 // if it is not null, making it safe (and cheap) to create these objects |
| 241 // even if activity tracking is not enabled. | 252 // even if activity tracking is not enabled. |
| 242 class BASE_EXPORT ScopedActivity { | 253 class BASE_EXPORT ScopedActivity { |
| 243 public: | 254 public: |
| 244 ScopedActivity(ThreadActivityTracker* tracker, | 255 ScopedActivity(ThreadActivityTracker* tracker, |
| 245 const void* origin, | 256 const void* origin, |
| 246 ActivityType type, | 257 Activity::Type type, |
| 247 const ActivityData& data) | 258 const ActivityData& data) |
| 248 : tracker_(tracker) { | 259 : tracker_(tracker) { |
| 249 if (tracker_) | 260 if (tracker_) |
| 250 tracker_->PushActivity(origin, type, data); | 261 tracker_->PushActivity(origin, type, data); |
| 251 } | 262 } |
| 252 | 263 |
| 253 ~ScopedActivity() { | 264 ~ScopedActivity() { |
| 254 if (tracker_) | 265 if (tracker_) |
| 255 tracker_->PopActivity(); | 266 tracker_->PopActivity(); |
| 256 } | 267 } |
| 257 | 268 |
| 258 void ChangeTypeAndData(ActivityType type, const ActivityData& data) { | 269 void ChangeTypeAndData(Activity::Type type, const ActivityData& data) { |
| 259 if (tracker_) | 270 if (tracker_) |
| 260 tracker_->ChangeActivity(type, data); | 271 tracker_->ChangeActivity(type, data); |
| 261 } | 272 } |
| 262 | 273 |
| 263 private: | 274 private: |
| 264 // The thread tracker to which this object reports. It can be null if | 275 // The thread tracker to which this object reports. It can be null if |
| 265 // activity tracking is not (yet) enabled. | 276 // activity tracking is not (yet) enabled. |
| 266 ThreadActivityTracker* const tracker_; | 277 ThreadActivityTracker* const tracker_; |
| 267 | 278 |
| 268 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); | 279 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); |
| 269 }; | 280 }; |
| 270 | 281 |
| 271 // A ThreadActivityTracker runs on top of memory that is managed externally. | 282 // A ThreadActivityTracker runs on top of memory that is managed externally. |
| 272 // It must be large enough for the internal header and a few Activity | 283 // It must be large enough for the internal header and a few Activity |
| 273 // blocks. See SizeForStackDepth(). | 284 // blocks. See SizeForStackDepth(). |
| 274 ThreadActivityTracker(void* base, size_t size); | 285 ThreadActivityTracker(void* base, size_t size); |
| 275 virtual ~ThreadActivityTracker(); | 286 virtual ~ThreadActivityTracker(); |
| 276 | 287 |
| 277 // Indicates that an activity has started from a given |origin| address in | 288 // Indicates that an activity has started from a given |origin| address in |
| 278 // the code, though it can be null if the creator's address is not known. | 289 // the code, though it can be null if the creator's address is not known. |
| 279 // The |type| and |data| describe the activity. | 290 // The |type| and |data| describe the activity. |
| 280 void PushActivity(const void* origin, | 291 void PushActivity(const void* origin, |
| 281 ActivityType type, | 292 Activity::Type type, |
| 282 const ActivityData& data); | 293 const ActivityData& data); |
| 283 | 294 |
| 284 // Changes the activity |type| and |data| of the top-most entry on the stack. | 295 // Changes the activity |type| and |data| of the top-most entry on the stack. |
| 285 // This is useful if the information has changed and it is desireable to | 296 // This is useful if the information has changed and it is desireable to |
| 286 // track that change without creating a new stack entry. If the type is | 297 // track that change without creating a new stack entry. If the type is |
| 287 // ACT_NULL or the data is kNullActivityData then that value will remain | 298 // ACT_NULL or the data is kNullActivityData then that value will remain |
| 288 // unchanged. The type, if changed, must remain in the same category. | 299 // unchanged. The type, if changed, must remain in the same category. |
| 289 // Changing both is not atomic so a snapshot operation could occur between | 300 // Changing both is not atomic so a snapshot operation could occur between |
| 290 // the update of |type| and |data| or between update of |data| fields. | 301 // the update of |type| and |data| or between update of |data| fields. |
| 291 void ChangeActivity(ActivityType type, const ActivityData& data); | 302 void ChangeActivity(Activity::Type type, const ActivityData& data); |
| 292 | 303 |
| 293 // Indicates that an activity has completed. | 304 // Indicates that an activity has completed. |
| 294 void PopActivity(); | 305 void PopActivity(); |
| 295 | 306 |
| 296 // Returns whether the current data is valid or not. It is not valid if | 307 // Returns whether the current data is valid or not. It is not valid if |
| 297 // corruption has been detected in the header or other data structures. | 308 // corruption has been detected in the header or other data structures. |
| 298 bool IsValid() const; | 309 bool IsValid() const; |
| 299 | 310 |
| 300 // Gets a copy of the tracker contents for analysis. Returns false if a | 311 // Gets a copy of the tracker contents for analysis. Returns false if a |
| 301 // snapshot was not possible, perhaps because the data is not valid; the | 312 // snapshot was not possible, perhaps because the data is not valid; the |
| 302 // contents of |output_snapshot| are undefined in that case. The current | 313 // contents of |output_snapshot| are undefined in that case. The current |
| 303 // implementation does not support concurrent snapshot operations. | 314 // implementation does not support concurrent snapshot operations. |
| 304 bool Snapshot(ActivitySnapshot* output_snapshot) const; | 315 bool Snapshot(ActivitySnapshot* output_snapshot) const; |
| 305 | 316 |
| 306 // Calculates the memory size required for a given stack depth, including | 317 // Calculates the memory size required for a given stack depth, including |
| 307 // the internal header structure for the stack. | 318 // the internal header structure for the stack. |
| 308 static size_t SizeForStackDepth(int stack_depth); | 319 static size_t SizeForStackDepth(int stack_depth); |
| 309 | 320 |
| 310 // A "null" activity-data that can be passed to indicate "do not change". | |
| 311 static const ActivityData kNullActivityData; | |
| 312 | |
| 313 private: | 321 private: |
| 314 friend class ActivityTrackerTest; | 322 friend class ActivityTrackerTest; |
| 315 | 323 |
| 316 // This structure contains all the common information about the thread so | 324 // This structure contains all the common information about the thread so |
| 317 // it doesn't have to be repeated in every entry on the stack. It is defined | 325 // it doesn't have to be repeated in every entry on the stack. It is defined |
| 318 // and used completely within the .cc file. | 326 // and used completely within the .cc file. |
| 319 struct Header; | 327 struct Header; |
| 320 | 328 |
| 321 Header* const header_; // Pointer to the Header structure. | 329 Header* const header_; // Pointer to the Header structure. |
| 322 Activity* const stack_; // The stack of activities. | 330 Activity* const stack_; // The stack of activities. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 347 }; | 355 }; |
| 348 | 356 |
| 349 // This is a thin wrapper around the thread-tracker's ScopedActivity that | 357 // This is a thin wrapper around the thread-tracker's ScopedActivity that |
| 350 // accesses the global tracker to provide some of the information, notably | 358 // accesses the global tracker to provide some of the information, notably |
| 351 // which thread-tracker to use. It is safe to create even if activity | 359 // which thread-tracker to use. It is safe to create even if activity |
| 352 // tracking is not enabled. | 360 // tracking is not enabled. |
| 353 class BASE_EXPORT ScopedThreadActivity | 361 class BASE_EXPORT ScopedThreadActivity |
| 354 : public ThreadActivityTracker::ScopedActivity { | 362 : public ThreadActivityTracker::ScopedActivity { |
| 355 public: | 363 public: |
| 356 ScopedThreadActivity(const void* origin, | 364 ScopedThreadActivity(const void* origin, |
| 357 ThreadActivityTracker::ActivityType type, | 365 Activity::Type type, |
| 358 const ThreadActivityTracker::ActivityData& data, | 366 const ActivityData& data, |
| 359 bool lock_allowed) | 367 bool lock_allowed) |
| 360 : ThreadActivityTracker::ScopedActivity( | 368 : ThreadActivityTracker::ScopedActivity( |
| 361 GetOrCreateTracker(lock_allowed), | 369 GetOrCreateTracker(lock_allowed), |
| 362 origin, | 370 origin, |
| 363 type, | 371 type, |
| 364 data) {} | 372 data) {} |
| 365 | 373 |
| 366 private: | 374 private: |
| 367 // Gets (or creates) a tracker for the current thread. If locking is not | 375 // Gets (or creates) a tracker for the current thread. If locking is not |
| 368 // allowed (because a lock is being tracked which would cause recursion) | 376 // allowed (because a lock is being tracked which would cause recursion) |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 explicit ScopedProcessWaitActivity(const base::Process* process); | 607 explicit ScopedProcessWaitActivity(const base::Process* process); |
| 600 private: | 608 private: |
| 601 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); | 609 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); |
| 602 }; | 610 }; |
| 603 #endif | 611 #endif |
| 604 | 612 |
| 605 } // namespace debug | 613 } // namespace debug |
| 606 } // namespace base | 614 } // namespace base |
| 607 | 615 |
| 608 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ | 616 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ |
| OLD | NEW |