diff options
| -rw-r--r-- | runtime/runtime.cc | 4 | ||||
| -rw-r--r-- | runtime/runtime.h | 4 | ||||
| -rw-r--r-- | runtime/signal_catcher.cc | 3 | ||||
| -rw-r--r-- | runtime/signal_catcher.h | 4 | ||||
| -rw-r--r-- | runtime/thread.cc | 7 |
5 files changed, 22 insertions, 0 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 97db5fb0fd..01aea2873a 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -2404,6 +2404,10 @@ void Runtime::DumpDeoptimizations(std::ostream& os) { } } +std::optional<uint64_t> Runtime::SiqQuitNanoTime() const { + return signal_catcher_ != nullptr ? signal_catcher_->SiqQuitNanoTime() : std::nullopt; +} + void Runtime::DumpForSigQuit(std::ostream& os) { // Print backtraces first since they are important do diagnose ANRs, // and ANRs can often be trimmed to limit upload size. diff --git a/runtime/runtime.h b/runtime/runtime.h index feb9cb3b7f..628109978c 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -23,6 +23,7 @@ #include <forward_list> #include <iosfwd> #include <memory> +#include <optional> #include <set> #include <string> #include <utility> @@ -311,6 +312,9 @@ class Runtime { // Detaches the current native thread from the runtime. void DetachCurrentThread(bool should_run_callbacks = true) REQUIRES(!Locks::mutator_lock_); + // If we are handling SIQQUIT return the time when we received it. + std::optional<uint64_t> SiqQuitNanoTime() const; + void DumpDeoptimizations(std::ostream& os); void DumpForSigQuit(std::ostream& os); void DumpLockHolders(std::ostream& os); diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc index 70cebafe4b..ba1b4efdd7 100644 --- a/runtime/signal_catcher.cc +++ b/runtime/signal_catcher.cc @@ -25,6 +25,7 @@ #include <sys/types.h> #include <unistd.h> +#include <optional> #include <sstream> #include <android-base/file.h> @@ -115,6 +116,7 @@ void SignalCatcher::Output(const std::string& s) { } void SignalCatcher::HandleSigQuit() { + sigquit_nanotime_ = NanoTime(); Runtime* runtime = Runtime::Current(); std::ostringstream os; os << "\n" @@ -140,6 +142,7 @@ void SignalCatcher::HandleSigQuit() { } os << "----- end " << getpid() << " -----\n"; Output(os.str()); + sigquit_nanotime_ = std::nullopt; } void SignalCatcher::HandleSigUsr1() { diff --git a/runtime/signal_catcher.h b/runtime/signal_catcher.h index 46eae7e50e..50b001d2ca 100644 --- a/runtime/signal_catcher.h +++ b/runtime/signal_catcher.h @@ -17,6 +17,8 @@ #ifndef ART_RUNTIME_SIGNAL_CATCHER_H_ #define ART_RUNTIME_SIGNAL_CATCHER_H_ +#include <optional> + #include "android-base/unique_fd.h" #include "base/mutex.h" @@ -39,6 +41,7 @@ class SignalCatcher { void HandleSigQuit() REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_); + std::optional<uint64_t> SiqQuitNanoTime() const { return sigquit_nanotime_; } private: // NO_THREAD_SAFETY_ANALYSIS for static function calling into member function with excludes lock. @@ -55,6 +58,7 @@ class SignalCatcher { bool halt_ GUARDED_BY(lock_); pthread_t pthread_ GUARDED_BY(lock_); Thread* thread_ GUARDED_BY(lock_); + std::optional<uint64_t> sigquit_nanotime_; }; } // namespace art diff --git a/runtime/thread.cc b/runtime/thread.cc index 9824e0a923..59d3da9395 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -29,6 +29,7 @@ #include <cerrno> #include <iostream> #include <list> +#include <optional> #include <sstream> #include "android-base/file.h" @@ -2362,6 +2363,7 @@ Thread::DumpOrder Thread::DumpStack(std::ostream& os, } DumpOrder dump_order = DumpOrder::kDefault; if (safe_to_dump || force_dump_stack) { + uint64_t nanotime = NanoTime(); // If we're currently in native code, dump that stack before dumping the managed stack. if (dump_native_stack && (dump_for_abort || force_dump_stack || ShouldShowNativeStack(this))) { ArtMethod* method = @@ -2373,6 +2375,11 @@ Thread::DumpOrder Thread::DumpStack(std::ostream& os, dump_order = DumpJavaStack(os, /*check_suspended=*/ !force_dump_stack, /*dump_locks=*/ !force_dump_stack); + Runtime* runtime = Runtime::Current(); + std::optional<uint64_t> start = runtime != nullptr ? runtime->SiqQuitNanoTime() : std::nullopt; + if (start.has_value()) { + os << "DumpLatencyMs: " << static_cast<float>(nanotime - start.value()) / 1000000.0 << "\n"; + } } else { os << "Not able to dump stack of thread that isn't suspended"; } |