| OLD | NEW |
| 1 // Copyright 2009 Google Inc. All Rights Reserved. | 1 // Copyright 2009 Google Inc. All Rights Reserved. |
| 2 // Author: Nabeel Mian (nabeelmian@google.com) | 2 // Author: Nabeel Mian (nabeelmian@google.com) |
| 3 // Chris Demetriou (cgd@google.com) | 3 // Chris Demetriou (cgd@google.com) |
| 4 // | 4 // |
| 5 // This file contains the unit tests for profile-handler.h interface. | 5 // This file contains the unit tests for profile-handler.h interface. |
| 6 | 6 |
| 7 #include "config.h" | 7 #include "config.h" |
| 8 #include "profile-handler.h" | 8 #include "profile-handler.h" |
| 9 | 9 |
| 10 #include <assert.h> | 10 #include <assert.h> |
| 11 #include <sys/time.h> |
| 11 #include <pthread.h> | 12 #include <pthread.h> |
| 12 #include <sys/time.h> | |
| 13 #include <time.h> | |
| 14 #include "base/logging.h" | 13 #include "base/logging.h" |
| 15 #include "base/simple_mutex.h" | 14 #include "base/simple_mutex.h" |
| 16 | 15 |
| 17 // Some helpful macros for the test class | 16 // Some helpful macros for the test class |
| 18 #define TEST_F(cls, fn) void cls :: fn() | 17 #define TEST_F(cls, fn) void cls :: fn() |
| 19 | 18 |
| 20 namespace { | 19 namespace { |
| 21 | 20 |
| 22 // TODO(csilvers): error-checking on the pthreads routines | 21 // TODO(csilvers): error-checking on the pthreads routines |
| 23 class Thread { | 22 class Thread { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 40 private: | 39 private: |
| 41 static void* DoRun(void* cls) { | 40 static void* DoRun(void* cls) { |
| 42 ProfileHandlerRegisterThread(); | 41 ProfileHandlerRegisterThread(); |
| 43 reinterpret_cast<Thread*>(cls)->Run(); | 42 reinterpret_cast<Thread*>(cls)->Run(); |
| 44 return NULL; | 43 return NULL; |
| 45 } | 44 } |
| 46 pthread_t thread_; | 45 pthread_t thread_; |
| 47 bool joinable_; | 46 bool joinable_; |
| 48 }; | 47 }; |
| 49 | 48 |
| 50 // timespec of the sleep interval. To ensure a SIGPROF timer interrupt under | 49 // Sleep interval in usecs. To ensure a SIGPROF timer interrupt under heavy |
| 51 // heavy load, this is set to a 20x of ProfileHandler timer interval (i.e 100Hz) | 50 // load, this is set to a 20x of ProfileHandler timer interval (i.e 100Hz) |
| 52 // TODO(nabeelmian) Under very heavy loads, the worker thread may not accumulate | 51 // TODO(nabeelmian) Under very heavy loads, the worker thread may not accumulate |
| 53 // enough cpu usage to get a profile tick. | 52 // enough cpu usage to get a profile tick. |
| 54 const struct timespec sleep_interval = { 0, 200000000 }; // 200 ms | 53 int kSleepInterval = 200000; |
| 55 | 54 |
| 56 // Whether each thread has separate timers. | 55 // Whether each thread has separate timers. |
| 57 static bool timer_separate_ = false; | 56 static bool timer_separate_ = false; |
| 58 | 57 |
| 59 // Checks whether the profile timer is enabled for the current thread. | 58 // Checks whether the profile timer is enabled for the current thread. |
| 60 bool IsTimerEnabled() { | 59 bool IsTimerEnabled() { |
| 61 itimerval current_timer; | 60 itimerval current_timer; |
| 62 EXPECT_EQ(0, getitimer(ITIMER_PROF, ¤t_timer)); | 61 EXPECT_EQ(0, getitimer(ITIMER_PROF, ¤t_timer)); |
| 63 return (current_timer.it_value.tv_sec != 0 || | 62 return (current_timer.it_value.tv_sec != 0 || |
| 64 current_timer.it_value.tv_usec != 0); | 63 current_timer.it_value.tv_usec != 0); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 | 206 |
| 208 // Starts a busy worker thread to accumulate cpu time. There should be only | 207 // Starts a busy worker thread to accumulate cpu time. There should be only |
| 209 // one busy worker running. This is required for the case where there are | 208 // one busy worker running. This is required for the case where there are |
| 210 // separate timers for each thread. | 209 // separate timers for each thread. |
| 211 void StartWorker() { | 210 void StartWorker() { |
| 212 busy_worker_ = new BusyThread(); | 211 busy_worker_ = new BusyThread(); |
| 213 busy_worker_->SetJoinable(true); | 212 busy_worker_->SetJoinable(true); |
| 214 busy_worker_->Start(); | 213 busy_worker_->Start(); |
| 215 // Wait for worker to start up and register with the ProfileHandler. | 214 // Wait for worker to start up and register with the ProfileHandler. |
| 216 // TODO(nabeelmian) This may not work under very heavy load. | 215 // TODO(nabeelmian) This may not work under very heavy load. |
| 217 nanosleep(&sleep_interval, NULL); | 216 usleep(kSleepInterval); |
| 218 } | 217 } |
| 219 | 218 |
| 220 // Stops the worker thread. | 219 // Stops the worker thread. |
| 221 void StopWorker() { | 220 void StopWorker() { |
| 222 busy_worker_->set_stop_work(true); | 221 busy_worker_->set_stop_work(true); |
| 223 busy_worker_->Join(); | 222 busy_worker_->Join(); |
| 224 delete busy_worker_; | 223 delete busy_worker_; |
| 225 } | 224 } |
| 226 | 225 |
| 227 // Checks whether SIGPROF signal handler is enabled. | 226 // Checks whether SIGPROF signal handler is enabled. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 251 void VerifyRegistration(const int& tick_counter) { | 250 void VerifyRegistration(const int& tick_counter) { |
| 252 // Check the callback count. | 251 // Check the callback count. |
| 253 EXPECT_GT(GetCallbackCount(), 0); | 252 EXPECT_GT(GetCallbackCount(), 0); |
| 254 // Check that the profile timer is enabled. | 253 // Check that the profile timer is enabled. |
| 255 EXPECT_TRUE(IsTimerEnabled()); | 254 EXPECT_TRUE(IsTimerEnabled()); |
| 256 // Check that the signal handler is enabled. | 255 // Check that the signal handler is enabled. |
| 257 EXPECT_TRUE(IsSignalEnabled()); | 256 EXPECT_TRUE(IsSignalEnabled()); |
| 258 uint64 interrupts_before = GetInterruptCount(); | 257 uint64 interrupts_before = GetInterruptCount(); |
| 259 // Sleep for a bit and check that tick counter is making progress. | 258 // Sleep for a bit and check that tick counter is making progress. |
| 260 int old_tick_count = tick_counter; | 259 int old_tick_count = tick_counter; |
| 261 nanosleep(&sleep_interval, NULL); | 260 usleep(kSleepInterval); |
| 262 int new_tick_count = tick_counter; | 261 int new_tick_count = tick_counter; |
| 263 EXPECT_GT(new_tick_count, old_tick_count); | 262 EXPECT_GT(new_tick_count, old_tick_count); |
| 264 uint64 interrupts_after = GetInterruptCount(); | 263 uint64 interrupts_after = GetInterruptCount(); |
| 265 EXPECT_GT(interrupts_after, interrupts_before); | 264 EXPECT_GT(interrupts_after, interrupts_before); |
| 266 } | 265 } |
| 267 | 266 |
| 268 // Verifies that a callback is not receiving profile ticks. | 267 // Verifies that a callback is not receiving profile ticks. |
| 269 void VerifyUnregistration(const int& tick_counter) { | 268 void VerifyUnregistration(const int& tick_counter) { |
| 270 // Sleep for a bit and check that tick counter is not making progress. | 269 // Sleep for a bit and check that tick counter is not making progress. |
| 271 int old_tick_count = tick_counter; | 270 int old_tick_count = tick_counter; |
| 272 nanosleep(&sleep_interval, NULL); | 271 usleep(kSleepInterval); |
| 273 int new_tick_count = tick_counter; | 272 int new_tick_count = tick_counter; |
| 274 EXPECT_EQ(new_tick_count, old_tick_count); | 273 EXPECT_EQ(new_tick_count, old_tick_count); |
| 275 // If no callbacks, signal handler and shared timer should be disabled. | 274 // If no callbacks, signal handler and shared timer should be disabled. |
| 276 if (GetCallbackCount() == 0) { | 275 if (GetCallbackCount() == 0) { |
| 277 EXPECT_FALSE(IsSignalEnabled()); | 276 EXPECT_FALSE(IsSignalEnabled()); |
| 278 if (timer_separate_) { | 277 if (timer_separate_) { |
| 279 EXPECT_TRUE(IsTimerEnabled()); | 278 EXPECT_TRUE(IsTimerEnabled()); |
| 280 } else { | 279 } else { |
| 281 EXPECT_FALSE(IsTimerEnabled()); | 280 EXPECT_FALSE(IsTimerEnabled()); |
| 282 } | 281 } |
| 283 } | 282 } |
| 284 } | 283 } |
| 285 | 284 |
| 286 // Verifies that the SIGPROF interrupt handler is disabled and the timer, | 285 // Verifies that the SIGPROF interrupt handler is disabled and the timer, |
| 287 // if shared, is disabled. Expects the worker to be running. | 286 // if shared, is disabled. Expects the worker to be running. |
| 288 void VerifyDisabled() { | 287 void VerifyDisabled() { |
| 289 // Check that the signal handler is disabled. | 288 // Check that the signal handler is disabled. |
| 290 EXPECT_FALSE(IsSignalEnabled()); | 289 EXPECT_FALSE(IsSignalEnabled()); |
| 291 // Check that the callback count is 0. | 290 // Check that the callback count is 0. |
| 292 EXPECT_EQ(GetCallbackCount(), 0); | 291 EXPECT_EQ(GetCallbackCount(), 0); |
| 293 // Check that the timer is disabled if shared, enabled otherwise. | 292 // Check that the timer is disabled if shared, enabled otherwise. |
| 294 if (timer_separate_) { | 293 if (timer_separate_) { |
| 295 EXPECT_TRUE(IsTimerEnabled()); | 294 EXPECT_TRUE(IsTimerEnabled()); |
| 296 } else { | 295 } else { |
| 297 EXPECT_FALSE(IsTimerEnabled()); | 296 EXPECT_FALSE(IsTimerEnabled()); |
| 298 } | 297 } |
| 299 // Verify that the ProfileHandler is not accumulating profile ticks. | 298 // Verify that the ProfileHandler is not accumulating profile ticks. |
| 300 uint64 interrupts_before = GetInterruptCount(); | 299 uint64 interrupts_before = GetInterruptCount(); |
| 301 nanosleep(&sleep_interval, NULL); | 300 usleep(kSleepInterval); |
| 302 uint64 interrupts_after = GetInterruptCount(); | 301 uint64 interrupts_after = GetInterruptCount(); |
| 303 EXPECT_EQ(interrupts_after, interrupts_before); | 302 EXPECT_EQ(interrupts_after, interrupts_before); |
| 304 } | 303 } |
| 305 | 304 |
| 306 // Busy worker thread to accumulate cpu usage. | 305 // Busy worker thread to accumulate cpu usage. |
| 307 BusyThread* busy_worker_; | 306 BusyThread* busy_worker_; |
| 308 | 307 |
| 309 private: | 308 private: |
| 310 // The tests to run | 309 // The tests to run |
| 311 void RegisterUnregisterCallback(); | 310 void RegisterUnregisterCallback(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 EXPECT_EQ(GetCallbackCount(), 1); | 427 EXPECT_EQ(GetCallbackCount(), 1); |
| 429 EXPECT_TRUE(IsTimerEnabled()); | 428 EXPECT_TRUE(IsTimerEnabled()); |
| 430 EXPECT_TRUE(IsSignalEnabled()); | 429 EXPECT_TRUE(IsSignalEnabled()); |
| 431 } | 430 } |
| 432 | 431 |
| 433 } // namespace | 432 } // namespace |
| 434 | 433 |
| 435 int main(int argc, char** argv) { | 434 int main(int argc, char** argv) { |
| 436 return ProfileHandlerTest::RUN_ALL_TESTS(); | 435 return ProfileHandlerTest::RUN_ALL_TESTS(); |
| 437 } | 436 } |
| OLD | NEW |