1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/tracked.h"
6
7 #include "base/stringprintf.h"
8 #include "base/tracked_objects.h"
9
10 using base::TimeTicks;
11
12 namespace tracked_objects {
13
14 //------------------------------------------------------------------------------
15
Location(const char * function_name,const char * file_name,int line_number)16 Location::Location(const char* function_name, const char* file_name,
17 int line_number)
18 : function_name_(function_name),
19 file_name_(file_name),
20 line_number_(line_number) {
21 }
22
Location()23 Location::Location()
24 : function_name_("Unknown"),
25 file_name_("Unknown"),
26 line_number_(-1) {
27 }
28
Write(bool display_filename,bool display_function_name,std::string * output) const29 void Location::Write(bool display_filename, bool display_function_name,
30 std::string* output) const {
31 base::StringAppendF(output, "%s[%d] ",
32 display_filename ? file_name_ : "line",
33 line_number_);
34
35 if (display_function_name) {
36 WriteFunctionName(output);
37 output->push_back(' ');
38 }
39 }
40
WriteFunctionName(std::string * output) const41 void Location::WriteFunctionName(std::string* output) const {
42 // Translate "<" to "<" for HTML safety.
43 // TODO(jar): Support ASCII or html for logging in ASCII.
44 for (const char *p = function_name_; *p; p++) {
45 switch (*p) {
46 case '<':
47 output->append("<");
48 break;
49
50 case '>':
51 output->append(">");
52 break;
53
54 default:
55 output->push_back(*p);
56 break;
57 }
58 }
59 }
60
61 //------------------------------------------------------------------------------
62
63 #ifndef TRACK_ALL_TASK_OBJECTS
64
Tracked()65 Tracked::Tracked() {}
~Tracked()66 Tracked::~Tracked() {}
SetBirthPlace(const Location & from_here)67 void Tracked::SetBirthPlace(const Location& from_here) {}
GetBirthPlace() const68 const Location Tracked::GetBirthPlace() const {
69 static Location kNone("NoFunctionName", "NeedToSetBirthPlace", -1);
70 return kNone;
71 }
MissingBirthplace() const72 bool Tracked::MissingBirthplace() const { return false; }
ResetBirthTime()73 void Tracked::ResetBirthTime() {}
74
75 #else
76
Tracked()77 Tracked::Tracked()
78 : tracked_births_(NULL),
79 tracked_birth_time_(TimeTicks::Now()) {
80 if (!ThreadData::IsActive())
81 return;
82 SetBirthPlace(Location("NoFunctionName", "NeedToSetBirthPlace", -1));
83 }
84
~Tracked()85 Tracked::~Tracked() {
86 if (!ThreadData::IsActive() || !tracked_births_)
87 return;
88 ThreadData::current()->TallyADeath(*tracked_births_,
89 TimeTicks::Now() - tracked_birth_time_);
90 }
91
SetBirthPlace(const Location & from_here)92 void Tracked::SetBirthPlace(const Location& from_here) {
93 if (!ThreadData::IsActive())
94 return;
95 if (tracked_births_)
96 tracked_births_->ForgetBirth();
97 ThreadData* current_thread_data = ThreadData::current();
98 if (!current_thread_data)
99 return; // Shutdown started, and this thread wasn't registered.
100 tracked_births_ = current_thread_data->TallyABirth(from_here);
101 }
102
GetBirthPlace() const103 const Location Tracked::GetBirthPlace() const {
104 return tracked_births_->location();
105 }
106
ResetBirthTime()107 void Tracked::ResetBirthTime() {
108 tracked_birth_time_ = TimeTicks::Now();
109 }
110
MissingBirthplace() const111 bool Tracked::MissingBirthplace() const {
112 return -1 == tracked_births_->location().line_number();
113 }
114
115 #endif // NDEBUG
116
117 } // namespace tracked_objects
118