| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/histogram.h" |
| 10 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/message_pump_default.h" | 13 #include "base/message_pump_default.h" |
| 13 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 14 #include "base/thread_local.h" | 15 #include "base/thread_local.h" |
| 15 | 16 |
| 16 #if defined(OS_MACOSX) | 17 #if defined(OS_MACOSX) |
| 17 #include "base/message_pump_mac.h" | 18 #include "base/message_pump_mac.h" |
| 18 #endif | 19 #endif |
| 19 #if defined(OS_POSIX) | 20 #if defined(OS_POSIX) |
| 20 #include "base/message_pump_libevent.h" | 21 #include "base/message_pump_libevent.h" |
| 21 #include "base/third_party/valgrind/valgrind.h" | 22 #include "base/third_party/valgrind/valgrind.h" |
| 22 #endif | 23 #endif |
| 23 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 24 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| 24 #include "base/message_pump_glib.h" | 25 #include "base/message_pump_glib.h" |
| 25 #endif | 26 #endif |
| 26 | 27 |
| 27 using base::Time; | 28 using base::Time; |
| 28 using base::TimeDelta; | 29 using base::TimeDelta; |
| 29 | 30 |
| 31 namespace { |
| 32 |
| 30 // A lazily created thread local storage for quick access to a thread's message | 33 // A lazily created thread local storage for quick access to a thread's message |
| 31 // loop, if one exists. This should be safe and free of static constructors. | 34 // loop, if one exists. This should be safe and free of static constructors. |
| 32 static base::LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr( | 35 base::LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr( |
| 33 base::LINKER_INITIALIZED); | 36 base::LINKER_INITIALIZED); |
| 34 | 37 |
| 38 // Logical events for Histogram profiling. Run with -message-loop-histogrammer |
| 39 // to get an accounting of messages and actions taken on each thread. |
| 40 const int kTaskRunEvent = 0x1; |
| 41 const int kTimerEvent = 0x2; |
| 42 |
| 43 // Provide range of message IDs for use in histogramming and debug display. |
| 44 const int kLeastNonZeroMessageId = 1; |
| 45 const int kMaxMessageId = 1099; |
| 46 const int kNumberOfDistinctMessagesDisplayed = 1100; |
| 47 |
| 48 // Provide a macro that takes an expression (such as a constant, or macro |
| 49 // constant) and creates a pair to initalize an array of pairs. In this case, |
| 50 // our pair consists of the expressions value, and the "stringized" version |
| 51 // of the expression (i.e., the exrpression put in quotes). For example, if |
| 52 // we have: |
| 53 // #define FOO 2 |
| 54 // #define BAR 5 |
| 55 // then the following: |
| 56 // VALUE_TO_NUMBER_AND_NAME(FOO + BAR) |
| 57 // will expand to: |
| 58 // {7, "FOO + BAR"} |
| 59 // We use the resulting array as an argument to our histogram, which reads the |
| 60 // number as a bucket identifier, and proceeds to use the corresponding name |
| 61 // in the pair (i.e., the quoted string) when printing out a histogram. |
| 62 #define VALUE_TO_NUMBER_AND_NAME(name) {name, #name}, |
| 63 |
| 64 const LinearHistogram::DescriptionPair event_descriptions_[] = { |
| 65 // Provide some pretty print capability in our histogram for our internal |
| 66 // messages. |
| 67 |
| 68 // A few events we handle (kindred to messages), and used to profile actions. |
| 69 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) |
| 70 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) |
| 71 |
| 72 {-1, NULL} // The list must be null terminated, per API to histogram. |
| 73 }; |
| 74 |
| 75 bool enable_histogrammer_ = false; |
| 76 |
| 77 } // namespace |
| 78 |
| 35 //------------------------------------------------------------------------------ | 79 //------------------------------------------------------------------------------ |
| 36 | 80 |
| 37 // Logical events for Histogram profiling. Run with -message-loop-histogrammer | |
| 38 // to get an accounting of messages and actions taken on each thread. | |
| 39 static const int kTaskRunEvent = 0x1; | |
| 40 static const int kTimerEvent = 0x2; | |
| 41 | |
| 42 // Provide range of message IDs for use in histogramming and debug display. | |
| 43 static const int kLeastNonZeroMessageId = 1; | |
| 44 static const int kMaxMessageId = 1099; | |
| 45 static const int kNumberOfDistinctMessagesDisplayed = 1100; | |
| 46 | |
| 47 //------------------------------------------------------------------------------ | |
| 48 | |
| 49 #if defined(OS_WIN) | 81 #if defined(OS_WIN) |
| 50 | 82 |
| 51 // Upon a SEH exception in this thread, it restores the original unhandled | 83 // Upon a SEH exception in this thread, it restores the original unhandled |
| 52 // exception filter. | 84 // exception filter. |
| 53 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { | 85 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { |
| 54 ::SetUnhandledExceptionFilter(old_filter); | 86 ::SetUnhandledExceptionFilter(old_filter); |
| 55 return EXCEPTION_CONTINUE_SEARCH; | 87 return EXCEPTION_CONTINUE_SEARCH; |
| 56 } | 88 } |
| 57 | 89 |
| 58 // Retrieves a pointer to the current unhandled exception filter. There | 90 // Retrieves a pointer to the current unhandled exception filter. There |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 // If the times happen to match, then we use the sequence number to decide. | 592 // If the times happen to match, then we use the sequence number to decide. |
| 561 // Compare the difference to support integer roll-over. | 593 // Compare the difference to support integer roll-over. |
| 562 return (sequence_num - other.sequence_num) > 0; | 594 return (sequence_num - other.sequence_num) > 0; |
| 563 } | 595 } |
| 564 | 596 |
| 565 //------------------------------------------------------------------------------ | 597 //------------------------------------------------------------------------------ |
| 566 // Method and data for histogramming events and actions taken by each instance | 598 // Method and data for histogramming events and actions taken by each instance |
| 567 // on each thread. | 599 // on each thread. |
| 568 | 600 |
| 569 // static | 601 // static |
| 570 bool MessageLoop::enable_histogrammer_ = false; | |
| 571 | |
| 572 // static | |
| 573 void MessageLoop::EnableHistogrammer(bool enable) { | 602 void MessageLoop::EnableHistogrammer(bool enable) { |
| 574 enable_histogrammer_ = enable; | 603 enable_histogrammer_ = enable; |
| 575 } | 604 } |
| 576 | 605 |
| 577 void MessageLoop::StartHistogrammer() { | 606 void MessageLoop::StartHistogrammer() { |
| 578 if (enable_histogrammer_ && !message_histogram_.get() | 607 if (enable_histogrammer_ && !message_histogram_.get() |
| 579 && StatisticsRecorder::WasStarted()) { | 608 && StatisticsRecorder::WasStarted()) { |
| 580 DCHECK(!thread_name_.empty()); | 609 DCHECK(!thread_name_.empty()); |
| 581 message_histogram_ = LinearHistogram::FactoryGet("MsgLoop:" + thread_name_, | 610 message_histogram_ = LinearHistogram::FactoryGet("MsgLoop:" + thread_name_, |
| 582 kLeastNonZeroMessageId, kMaxMessageId, | 611 kLeastNonZeroMessageId, kMaxMessageId, |
| 583 kNumberOfDistinctMessagesDisplayed, | 612 kNumberOfDistinctMessagesDisplayed, |
| 584 message_histogram_->kHexRangePrintingFlag); | 613 message_histogram_->kHexRangePrintingFlag); |
| 585 message_histogram_->SetRangeDescriptions(event_descriptions_); | 614 message_histogram_->SetRangeDescriptions(event_descriptions_); |
| 586 } | 615 } |
| 587 } | 616 } |
| 588 | 617 |
| 589 void MessageLoop::HistogramEvent(int event) { | 618 void MessageLoop::HistogramEvent(int event) { |
| 590 if (message_histogram_.get()) | 619 if (message_histogram_.get()) |
| 591 message_histogram_->Add(event); | 620 message_histogram_->Add(event); |
| 592 } | 621 } |
| 593 | 622 |
| 594 // Provide a macro that takes an expression (such as a constant, or macro | |
| 595 // constant) and creates a pair to initalize an array of pairs. In this case, | |
| 596 // our pair consists of the expressions value, and the "stringized" version | |
| 597 // of the expression (i.e., the exrpression put in quotes). For example, if | |
| 598 // we have: | |
| 599 // #define FOO 2 | |
| 600 // #define BAR 5 | |
| 601 // then the following: | |
| 602 // VALUE_TO_NUMBER_AND_NAME(FOO + BAR) | |
| 603 // will expand to: | |
| 604 // {7, "FOO + BAR"} | |
| 605 // We use the resulting array as an argument to our histogram, which reads the | |
| 606 // number as a bucket identifier, and proceeds to use the corresponding name | |
| 607 // in the pair (i.e., the quoted string) when printing out a histogram. | |
| 608 #define VALUE_TO_NUMBER_AND_NAME(name) {name, #name}, | |
| 609 | |
| 610 // static | |
| 611 const LinearHistogram::DescriptionPair MessageLoop::event_descriptions_[] = { | |
| 612 // Provide some pretty print capability in our histogram for our internal | |
| 613 // messages. | |
| 614 | |
| 615 // A few events we handle (kindred to messages), and used to profile actions. | |
| 616 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) | |
| 617 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) | |
| 618 | |
| 619 {-1, NULL} // The list must be null terminated, per API to histogram. | |
| 620 }; | |
| 621 | |
| 622 //------------------------------------------------------------------------------ | 623 //------------------------------------------------------------------------------ |
| 623 // MessageLoopForUI | 624 // MessageLoopForUI |
| 624 | 625 |
| 625 #if defined(OS_WIN) | 626 #if defined(OS_WIN) |
| 626 void MessageLoopForUI::DidProcessMessage(const MSG& message) { | 627 void MessageLoopForUI::DidProcessMessage(const MSG& message) { |
| 627 pump_win()->DidProcessMessage(message); | 628 pump_win()->DidProcessMessage(message); |
| 628 } | 629 } |
| 629 #endif // defined(OS_WIN) | 630 #endif // defined(OS_WIN) |
| 630 | 631 |
| 631 #if !defined(OS_MACOSX) | 632 #if !defined(OS_MACOSX) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 Watcher *delegate) { | 667 Watcher *delegate) { |
| 667 return pump_libevent()->WatchFileDescriptor( | 668 return pump_libevent()->WatchFileDescriptor( |
| 668 fd, | 669 fd, |
| 669 persistent, | 670 persistent, |
| 670 static_cast<base::MessagePumpLibevent::Mode>(mode), | 671 static_cast<base::MessagePumpLibevent::Mode>(mode), |
| 671 controller, | 672 controller, |
| 672 delegate); | 673 delegate); |
| 673 } | 674 } |
| 674 | 675 |
| 675 #endif | 676 #endif |
| OLD | NEW |