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

Side by Side Diff: third_party/tcmalloc/chromium/src/profile-handler.cc

Issue 576001: Merged third_party/tcmalloc/vendor/src(google-perftools r87) into... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Removed the unnecessary printf and ASSERT(0) Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009, Google Inc. 1 // Copyright (c) 2009, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 // 82 //
83 // Prior to determining whether timers are shared, this function will 83 // Prior to determining whether timers are shared, this function will
84 // unconditionally start the timer. However, if this function determines 84 // unconditionally start the timer. However, if this function determines
85 // that timers are shared, then it will stop the timer if no callbacks are 85 // that timers are shared, then it will stop the timer if no callbacks are
86 // currently registered. 86 // currently registered.
87 void RegisterThread(); 87 void RegisterThread();
88 88
89 // Registers a callback routine to receive profile timer ticks. The returned 89 // Registers a callback routine to receive profile timer ticks. The returned
90 // token is to be used when unregistering this callback and must not be 90 // token is to be used when unregistering this callback and must not be
91 // deleted by the caller. Registration of the first callback enables the 91 // deleted by the caller. Registration of the first callback enables the
92 // SIGPROF handler. 92 // SIGPROF handler (or SIGALRM if using ITIMER_REAL).
93 ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback, 93 ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback,
94 void* callback_arg); 94 void* callback_arg);
95 95
96 // Unregisters a previously registered callback. Expects the token returned 96 // Unregisters a previously registered callback. Expects the token returned
97 // by the corresponding RegisterCallback routine. Unregistering the last 97 // by the corresponding RegisterCallback routine. Unregistering the last
98 // callback disables the SIGPROF handler. 98 // callback disables the SIGPROF handler (or SIGALRM if using ITIMER_REAL).
99 void UnregisterCallback(ProfileHandlerToken* token) 99 void UnregisterCallback(ProfileHandlerToken* token)
100 NO_THREAD_SAFETY_ANALYSIS; 100 NO_THREAD_SAFETY_ANALYSIS;
101 101
102 // Unregisters all the callbacks, stops the timer if shared, disables the 102 // Unregisters all the callbacks, stops the timer if shared, disables the
103 // SIGPROF handler and clears the timer_sharing_ state. 103 // SIGPROF (or SIGALRM) handler and clears the timer_sharing_ state.
104 void Reset(); 104 void Reset();
105 105
106 // Gets the current state of profile handler. 106 // Gets the current state of profile handler.
107 void GetState(ProfileHandlerState* state); 107 void GetState(ProfileHandlerState* state);
108 108
109 // Initializes and returns the ProfileHandler singleton. 109 // Initializes and returns the ProfileHandler singleton.
110 static ProfileHandler* Instance(); 110 static ProfileHandler* Instance();
111 111
112 private: 112 private:
113 ProfileHandler(); 113 ProfileHandler();
114 ~ProfileHandler(); 114 ~ProfileHandler();
115 115
116 // Largest allowed frequency. 116 // Largest allowed frequency.
117 static const int32 kMaxFrequency = 4000; 117 static const int32 kMaxFrequency = 4000;
118 // Default frequency. 118 // Default frequency.
119 static const int32 kDefaultFrequency = 100; 119 static const int32 kDefaultFrequency = 100;
120 120
121 // ProfileHandler singleton. 121 // ProfileHandler singleton.
122 static ProfileHandler* instance_; 122 static ProfileHandler* instance_;
123 123
124 // pthread_once_t for one time initialization of ProfileHandler singleton. 124 // pthread_once_t for one time initialization of ProfileHandler singleton.
125 static pthread_once_t once_; 125 static pthread_once_t once_;
126 126
127 // Initializes the ProfileHandler singleton via GoogleOnceInit. 127 // Initializes the ProfileHandler singleton via GoogleOnceInit.
128 static void Init(); 128 static void Init();
129 129
130 // Counts the number of SIGPROF interrupts received. 130 // The number of SIGPROF (or SIGALRM for ITIMER_REAL) interrupts received.
131 int64 interrupts_ GUARDED_BY(signal_lock_); 131 int64 interrupts_ GUARDED_BY(signal_lock_);
132 132
133 // SIGPROF interrupt frequency, read-only after construction. 133 // SIGPROF/SIGALRM interrupt frequency, read-only after construction.
134 int32 frequency_; 134 int32 frequency_;
135 135
136 // ITIMER_PROF (which uses SIGPROF), or ITIMER_REAL (which uses SIGALRM)
137 int timer_type_;
138
136 // Counts the number of callbacks registered. 139 // Counts the number of callbacks registered.
137 int32 callback_count_ GUARDED_BY(control_lock_); 140 int32 callback_count_ GUARDED_BY(control_lock_);
138 141
139 // Whether or not the threading system provides interval timers that are 142 // Whether or not the threading system provides interval timers that are
140 // shared by all threads in a process. 143 // shared by all threads in a process.
141 enum { 144 enum {
142 // No timer initialization attempted yet. 145 // No timer initialization attempted yet.
143 TIMERS_UNTOUCHED, 146 TIMERS_UNTOUCHED,
144 // First thread has registered and set timer. 147 // First thread has registered and set timer.
145 TIMERS_ONE_SET, 148 TIMERS_ONE_SET,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 // thread. This actually checks the kernel's interval timer setting. (It is 192 // thread. This actually checks the kernel's interval timer setting. (It is
190 // used to detect whether timers are shared or separate.) 193 // used to detect whether timers are shared or separate.)
191 bool IsTimerRunning() EXCLUSIVE_LOCKS_REQUIRED(control_lock_); 194 bool IsTimerRunning() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
192 195
193 // Sets the timer interrupt signal handler. 196 // Sets the timer interrupt signal handler.
194 void EnableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_); 197 void EnableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
195 198
196 // Disables (ignores) the timer interrupt signal. 199 // Disables (ignores) the timer interrupt signal.
197 void DisableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_); 200 void DisableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
198 201
199 // SIGPROF handler. Iterate over and call all the registered callbacks. 202 // SIGPROF/SIGALRM handler. Iterate over and call all the registered callbacks .
200 static void SignalHandler(int sig, siginfo_t* sinfo, void* ucontext); 203 static void SignalHandler(int sig, siginfo_t* sinfo, void* ucontext);
201 204
202 DISALLOW_EVIL_CONSTRUCTORS(ProfileHandler); 205 DISALLOW_COPY_AND_ASSIGN(ProfileHandler);
203 }; 206 };
204 207
205 ProfileHandler* ProfileHandler::instance_ = NULL; 208 ProfileHandler* ProfileHandler::instance_ = NULL;
206 pthread_once_t ProfileHandler::once_ = PTHREAD_ONCE_INIT; 209 pthread_once_t ProfileHandler::once_ = PTHREAD_ONCE_INIT;
207 210
208 const int32 ProfileHandler::kMaxFrequency; 211 const int32 ProfileHandler::kMaxFrequency;
209 const int32 ProfileHandler::kDefaultFrequency; 212 const int32 ProfileHandler::kDefaultFrequency;
210 213
211 // If we are LD_PRELOAD-ed against a non-pthreads app, then 214 // If we are LD_PRELOAD-ed against a non-pthreads app, then
212 // pthread_once won't be defined. We declare it here, for that 215 // pthread_once won't be defined. We declare it here, for that
(...skipping 21 matching lines...) Expand all
234 assert(instance_ != NULL); 237 assert(instance_ != NULL);
235 } 238 }
236 return instance_; 239 return instance_;
237 } 240 }
238 241
239 ProfileHandler::ProfileHandler() 242 ProfileHandler::ProfileHandler()
240 : interrupts_(0), 243 : interrupts_(0),
241 callback_count_(0), 244 callback_count_(0),
242 timer_sharing_(TIMERS_UNTOUCHED) { 245 timer_sharing_(TIMERS_UNTOUCHED) {
243 SpinLockHolder cl(&control_lock_); 246 SpinLockHolder cl(&control_lock_);
247
248 timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
249
244 // Get frequency of interrupts (if specified) 250 // Get frequency of interrupts (if specified)
245 char junk; 251 char junk;
246 const char* fr = getenv("CPUPROFILE_FREQUENCY"); 252 const char* fr = getenv("CPUPROFILE_FREQUENCY");
247 if (fr != NULL && (sscanf(fr, "%u%c", &frequency_, &junk) == 1) && 253 if (fr != NULL && (sscanf(fr, "%u%c", &frequency_, &junk) == 1) &&
248 (frequency_ > 0)) { 254 (frequency_ > 0)) {
249 // Limit to kMaxFrequency 255 // Limit to kMaxFrequency
250 frequency_ = (frequency_ > kMaxFrequency) ? kMaxFrequency : frequency_; 256 frequency_ = (frequency_ > kMaxFrequency) ? kMaxFrequency : frequency_;
251 } else { 257 } else {
252 frequency_ = kDefaultFrequency; 258 frequency_ = kDefaultFrequency;
253 } 259 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 389 }
384 state->frequency = frequency_; 390 state->frequency = frequency_;
385 state->callback_count = callback_count_; 391 state->callback_count = callback_count_;
386 } 392 }
387 393
388 void ProfileHandler::StartTimer() { 394 void ProfileHandler::StartTimer() {
389 struct itimerval timer; 395 struct itimerval timer;
390 timer.it_interval.tv_sec = 0; 396 timer.it_interval.tv_sec = 0;
391 timer.it_interval.tv_usec = 1000000 / frequency_; 397 timer.it_interval.tv_usec = 1000000 / frequency_;
392 timer.it_value = timer.it_interval; 398 timer.it_value = timer.it_interval;
393 setitimer(ITIMER_PROF, &timer, 0); 399 setitimer(timer_type_, &timer, 0);
394 } 400 }
395 401
396 void ProfileHandler::StopTimer() { 402 void ProfileHandler::StopTimer() {
397 struct itimerval timer; 403 struct itimerval timer;
398 memset(&timer, 0, sizeof timer); 404 memset(&timer, 0, sizeof timer);
399 setitimer(ITIMER_PROF, &timer, 0); 405 setitimer(timer_type_, &timer, 0);
400 } 406 }
401 407
402 bool ProfileHandler::IsTimerRunning() { 408 bool ProfileHandler::IsTimerRunning() {
403 struct itimerval current_timer; 409 struct itimerval current_timer;
404 RAW_CHECK(0 == getitimer(ITIMER_PROF, &current_timer), "getitimer"); 410 RAW_CHECK(0 == getitimer(timer_type_, &current_timer), "getitimer");
405 return (current_timer.it_value.tv_sec != 0 || 411 return (current_timer.it_value.tv_sec != 0 ||
406 current_timer.it_value.tv_usec != 0); 412 current_timer.it_value.tv_usec != 0);
407 } 413 }
408 414
409 void ProfileHandler::EnableHandler() { 415 void ProfileHandler::EnableHandler() {
410 struct sigaction sa; 416 struct sigaction sa;
411 sa.sa_sigaction = SignalHandler; 417 sa.sa_sigaction = SignalHandler;
412 sa.sa_flags = SA_RESTART | SA_SIGINFO; 418 sa.sa_flags = SA_RESTART | SA_SIGINFO;
413 sigemptyset(&sa.sa_mask); 419 sigemptyset(&sa.sa_mask);
414 RAW_CHECK(sigaction(SIGPROF, &sa, NULL) == 0, "sigprof (enable)"); 420 const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
421 RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, "sigprof (enable)");
415 } 422 }
416 423
417 void ProfileHandler::DisableHandler() { 424 void ProfileHandler::DisableHandler() {
418 struct sigaction sa; 425 struct sigaction sa;
419 sa.sa_handler = SIG_IGN; 426 sa.sa_handler = SIG_IGN;
420 sa.sa_flags = SA_RESTART; 427 sa.sa_flags = SA_RESTART;
421 sigemptyset(&sa.sa_mask); 428 sigemptyset(&sa.sa_mask);
422 RAW_CHECK(sigaction(SIGPROF, &sa, NULL) == 0, "sigprof (disable)"); 429 const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
430 RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, "sigprof (disable)");
423 } 431 }
424 432
425 void ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) { 433 void ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) {
426 int saved_errno = errno; 434 int saved_errno = errno;
427 RAW_CHECK(instance_ != NULL, "ProfileHandler is not initialized"); 435 RAW_CHECK(instance_ != NULL, "ProfileHandler is not initialized");
428 { 436 {
429 SpinLockHolder sl(&instance_->signal_lock_); 437 SpinLockHolder sl(&instance_->signal_lock_);
430 ++instance_->interrupts_; 438 ++instance_->interrupts_;
431 for (CallbackIterator it = instance_->callbacks_.begin(); 439 for (CallbackIterator it = instance_->callbacks_.begin();
432 it != instance_->callbacks_.end(); 440 it != instance_->callbacks_.end();
433 ++it) { 441 ++it) {
434 (*it)->callback(sig, sinfo, ucontext, (*it)->callback_arg); 442 (*it)->callback(sig, sinfo, ucontext, (*it)->callback_arg);
435 } 443 }
436 } 444 }
437 errno = saved_errno; 445 errno = saved_errno;
438 } 446 }
439 447
440 // The sole purpose of this class is to initialize the ProfileHandler singleton 448 // The sole purpose of this class is to initialize the ProfileHandler singleton
441 // when the global static objects are created. Note that the main thread will 449 // when the global static objects are created. Note that the main thread will
442 // be registered at this time. 450 // be registered at this time.
443 class ProfileHandlerInitializer { 451 class ProfileHandlerInitializer {
444 public: 452 public:
445 ProfileHandlerInitializer() { 453 ProfileHandlerInitializer() {
446 ProfileHandler::Instance()->RegisterThread(); 454 ProfileHandler::Instance()->RegisterThread();
447 } 455 }
448 456
449 private: 457 private:
450 DISALLOW_EVIL_CONSTRUCTORS(ProfileHandlerInitializer); 458 DISALLOW_COPY_AND_ASSIGN(ProfileHandlerInitializer);
451 }; 459 };
452 // ProfileHandlerInitializer singleton 460 // ProfileHandlerInitializer singleton
453 static ProfileHandlerInitializer profile_handler_initializer; 461 static ProfileHandlerInitializer profile_handler_initializer;
454 462
455 extern "C" void ProfileHandlerRegisterThread() { 463 extern "C" void ProfileHandlerRegisterThread() {
456 ProfileHandler::Instance()->RegisterThread(); 464 ProfileHandler::Instance()->RegisterThread();
457 } 465 }
458 466
459 extern "C" ProfileHandlerToken* ProfileHandlerRegisterCallback( 467 extern "C" ProfileHandlerToken* ProfileHandlerRegisterCallback(
460 ProfileHandlerCallback callback, void* callback_arg) { 468 ProfileHandlerCallback callback, void* callback_arg) {
(...skipping 29 matching lines...) Expand all
490 extern "C" void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) { 498 extern "C" void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {
491 } 499 }
492 500
493 extern "C" void ProfileHandlerReset() { 501 extern "C" void ProfileHandlerReset() {
494 } 502 }
495 503
496 extern "C" void ProfileHandlerGetState(ProfileHandlerState* state) { 504 extern "C" void ProfileHandlerGetState(ProfileHandlerState* state) {
497 } 505 }
498 506
499 #endif // OS_CYGWIN 507 #endif // OS_CYGWIN
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/pprof ('k') | third_party/tcmalloc/chromium/src/profiledata.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698