michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "base/tracked.h" michael@0: michael@0: #include "base/string_util.h" michael@0: #include "base/tracked_objects.h" michael@0: michael@0: using base::Time; michael@0: michael@0: namespace tracked_objects { michael@0: michael@0: //------------------------------------------------------------------------------ michael@0: void Location::Write(bool display_filename, bool display_function_name, michael@0: std::string* output) const { michael@0: StringAppendF(output, "%s[%d] ", michael@0: display_filename ? file_name_ : "line", michael@0: line_number_); michael@0: michael@0: if (display_function_name) { michael@0: WriteFunctionName(output); michael@0: output->push_back(' '); michael@0: } michael@0: } michael@0: michael@0: void Location::WriteFunctionName(std::string* output) const { michael@0: // Translate "<" to "<" for HTML safety. michael@0: // TODO(jar): Support ASCII or html for logging in ASCII. michael@0: for (const char *p = function_name_; *p; p++) { michael@0: switch (*p) { michael@0: case '<': michael@0: output->append("<"); michael@0: break; michael@0: michael@0: case '>': michael@0: output->append(">"); michael@0: break; michael@0: michael@0: default: michael@0: output->push_back(*p); michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: michael@0: //------------------------------------------------------------------------------ michael@0: michael@0: #ifndef TRACK_ALL_TASK_OBJECTS michael@0: michael@0: Tracked::Tracked() {} michael@0: Tracked::~Tracked() {} michael@0: void Tracked::SetBirthPlace(const Location& from_here) {} michael@0: bool Tracked::MissingBirthplace() const { return false; } michael@0: void Tracked::ResetBirthTime() {} michael@0: michael@0: #else michael@0: michael@0: Tracked::Tracked() : tracked_births_(NULL), tracked_birth_time_(Time::Now()) { michael@0: if (!ThreadData::IsActive()) michael@0: return; michael@0: SetBirthPlace(Location("NoFunctionName", "NeedToSetBirthPlace", -1)); michael@0: } michael@0: michael@0: Tracked::~Tracked() { michael@0: if (!ThreadData::IsActive() || !tracked_births_) michael@0: return; michael@0: ThreadData::current()->TallyADeath(*tracked_births_, michael@0: Time::Now() - tracked_birth_time_); michael@0: } michael@0: michael@0: void Tracked::SetBirthPlace(const Location& from_here) { michael@0: if (!ThreadData::IsActive()) michael@0: return; michael@0: if (tracked_births_) michael@0: tracked_births_->ForgetBirth(); michael@0: ThreadData* current_thread_data = ThreadData::current(); michael@0: if (!current_thread_data) michael@0: return; // Shutdown started, and this thread wasn't registered. michael@0: tracked_births_ = current_thread_data->FindLifetime(from_here); michael@0: tracked_births_->RecordBirth(); michael@0: } michael@0: michael@0: void Tracked::ResetBirthTime() { michael@0: tracked_birth_time_ = Time::Now(); michael@0: } michael@0: michael@0: bool Tracked::MissingBirthplace() const { michael@0: return -1 == tracked_births_->location().line_number(); michael@0: } michael@0: michael@0: #endif // NDEBUG michael@0: michael@0: } // namespace tracked_objects