OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "net/disk_cache/trace.h" | 5 #include "net/disk_cache/trace.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #if defined(OS_WIN) | 8 #if defined(OS_WIN) |
9 #include <windows.h> | 9 #include <windows.h> |
10 #endif | 10 #endif |
11 | 11 |
| 12 #include "base/lazy_instance.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/synchronization/lock.h" |
13 #include "net/disk_cache/stress_support.h" | 15 #include "net/disk_cache/stress_support.h" |
14 | 16 |
15 // Change this value to 1 to enable tracing on a release build. By default, | 17 // Change this value to 1 to enable tracing on a release build. By default, |
16 // tracing is enabled only on debug builds. | 18 // tracing is enabled only on debug builds. |
17 #define ENABLE_TRACING 0 | 19 #define ENABLE_TRACING 0 |
18 | 20 |
19 #ifndef NDEBUG | 21 #ifndef NDEBUG |
20 #undef ENABLE_TRACING | 22 #undef ENABLE_TRACING |
21 #define ENABLE_TRACING 1 | 23 #define ENABLE_TRACING 1 |
22 #endif | 24 #endif |
23 | 25 |
24 namespace { | 26 namespace { |
25 | 27 |
26 const int kEntrySize = 12 * sizeof(size_t); | 28 const int kEntrySize = 12 * sizeof(size_t); |
27 #if defined(NET_BUILD_STRESS_CACHE) | 29 #if defined(NET_BUILD_STRESS_CACHE) |
28 const int kNumberOfEntries = 500000; | 30 const int kNumberOfEntries = 500000; |
29 #else | 31 #else |
30 const int kNumberOfEntries = 5000; // 240 KB on 32bit, 480 KB on 64bit | 32 const int kNumberOfEntries = 5000; // 240 KB on 32bit, 480 KB on 64bit |
31 #endif | 33 #endif |
32 | 34 |
33 bool s_trace_enabled = false; | 35 bool s_trace_enabled = false; |
| 36 base::LazyInstance<base::Lock>::Leaky s_lock = LAZY_INSTANCE_INITIALIZER; |
34 | 37 |
35 struct TraceBuffer { | 38 struct TraceBuffer { |
36 int num_traces; | 39 int num_traces; |
37 int current; | 40 int current; |
38 char buffer[kNumberOfEntries][kEntrySize]; | 41 char buffer[kNumberOfEntries][kEntrySize]; |
39 }; | 42 }; |
40 | 43 |
41 #if ENABLE_TRACING | 44 #if ENABLE_TRACING |
42 void DebugOutput(const char* msg) { | 45 void DebugOutput(const char* msg) { |
43 #if defined(OS_WIN) | 46 #if defined(OS_WIN) |
44 OutputDebugStringA(msg); | 47 OutputDebugStringA(msg); |
45 #else | 48 #else |
46 NOTIMPLEMENTED(); | 49 NOTIMPLEMENTED(); |
47 #endif | 50 #endif |
48 } | 51 } |
49 #endif // ENABLE_TRACING | 52 #endif // ENABLE_TRACING |
50 | 53 |
51 } // namespace | 54 } // namespace |
52 | 55 |
53 namespace disk_cache { | 56 namespace disk_cache { |
54 | 57 |
55 // s_trace_buffer and s_trace_object are not singletons because I want the | 58 // s_trace_buffer and s_trace_object are not singletons because I want the |
56 // buffer to be destroyed and re-created when the last user goes away, and it | 59 // buffer to be destroyed and re-created when the last user goes away, and it |
57 // must be straightforward to access the buffer from the debugger. | 60 // must be straightforward to access the buffer from the debugger. |
58 static TraceObject* s_trace_object = NULL; | 61 static TraceObject* s_trace_object = NULL; |
59 | 62 |
60 // Static. | 63 // Static. |
61 TraceObject* TraceObject::GetTraceObject() { | 64 TraceObject* TraceObject::GetTraceObject() { |
| 65 base::AutoLock lock(s_lock.Get()); |
| 66 |
62 if (s_trace_object) | 67 if (s_trace_object) |
63 return s_trace_object; | 68 return s_trace_object; |
64 | 69 |
65 s_trace_object = new TraceObject(); | 70 s_trace_object = new TraceObject(); |
66 return s_trace_object; | 71 return s_trace_object; |
67 } | 72 } |
68 | 73 |
69 TraceObject::TraceObject() { | 74 TraceObject::TraceObject() { |
70 InitTrace(); | 75 InitTrace(); |
71 } | 76 } |
72 | 77 |
73 TraceObject::~TraceObject() { | 78 TraceObject::~TraceObject() { |
74 DestroyTrace(); | 79 DestroyTrace(); |
75 } | 80 } |
76 | 81 |
77 void TraceObject::EnableTracing(bool enable) { | 82 void TraceObject::EnableTracing(bool enable) { |
| 83 base::AutoLock lock(s_lock.Get()); |
78 s_trace_enabled = enable; | 84 s_trace_enabled = enable; |
79 } | 85 } |
80 | 86 |
81 #if ENABLE_TRACING | 87 #if ENABLE_TRACING |
82 | 88 |
83 static TraceBuffer* s_trace_buffer = NULL; | 89 static TraceBuffer* s_trace_buffer = NULL; |
84 | 90 |
85 void InitTrace(void) { | 91 void InitTrace(void) { |
86 s_trace_enabled = true; | 92 s_trace_enabled = true; |
87 if (s_trace_buffer) | 93 if (s_trace_buffer) |
88 return; | 94 return; |
89 | 95 |
90 s_trace_buffer = new TraceBuffer; | 96 s_trace_buffer = new TraceBuffer; |
91 memset(s_trace_buffer, 0, sizeof(*s_trace_buffer)); | 97 memset(s_trace_buffer, 0, sizeof(*s_trace_buffer)); |
92 } | 98 } |
93 | 99 |
94 void DestroyTrace(void) { | 100 void DestroyTrace(void) { |
| 101 base::AutoLock lock(s_lock.Get()); |
| 102 |
95 delete s_trace_buffer; | 103 delete s_trace_buffer; |
96 s_trace_buffer = NULL; | 104 s_trace_buffer = NULL; |
97 s_trace_object = NULL; | 105 s_trace_object = NULL; |
98 } | 106 } |
99 | 107 |
100 void Trace(const char* format, ...) { | 108 void Trace(const char* format, ...) { |
101 if (!s_trace_buffer || !s_trace_enabled) | 109 if (!s_trace_buffer || !s_trace_enabled) |
102 return; | 110 return; |
103 | 111 |
104 va_list ap; | 112 va_list ap; |
105 va_start(ap, format); | 113 va_start(ap, format); |
| 114 char line[kEntrySize + 2]; |
106 | 115 |
107 #if defined(OS_WIN) | 116 #if defined(OS_WIN) |
108 vsprintf_s(s_trace_buffer->buffer[s_trace_buffer->current], format, ap); | 117 vsprintf_s(line, format, ap); |
109 #else | 118 #else |
110 vsnprintf(s_trace_buffer->buffer[s_trace_buffer->current], | 119 vsnprintf(line, kEntrySize, format, ap); |
111 sizeof(s_trace_buffer->buffer[s_trace_buffer->current]), format, | |
112 ap); | |
113 #endif | 120 #endif |
114 | 121 |
115 #if defined(DISK_CACHE_TRACE_TO_LOG) | 122 #if defined(DISK_CACHE_TRACE_TO_LOG) |
116 char line[kEntrySize + 2]; | |
117 memcpy(line, s_trace_buffer->buffer[s_trace_buffer->current], kEntrySize); | |
118 line[kEntrySize] = '\0'; | 123 line[kEntrySize] = '\0'; |
119 LOG(INFO) << line; | 124 LOG(INFO) << line; |
120 #endif | 125 #endif |
121 | 126 |
122 s_trace_buffer->num_traces++; | 127 va_end(ap); |
123 s_trace_buffer->current++; | |
124 if (s_trace_buffer->current == kNumberOfEntries) | |
125 s_trace_buffer->current = 0; | |
126 | 128 |
127 va_end(ap); | 129 { |
| 130 base::AutoLock lock(s_lock.Get()); |
| 131 if (!s_trace_buffer || !s_trace_enabled) |
| 132 return; |
| 133 |
| 134 memcpy(s_trace_buffer->buffer[s_trace_buffer->current], line, kEntrySize); |
| 135 |
| 136 s_trace_buffer->num_traces++; |
| 137 s_trace_buffer->current++; |
| 138 if (s_trace_buffer->current == kNumberOfEntries) |
| 139 s_trace_buffer->current = 0; |
| 140 } |
128 } | 141 } |
129 | 142 |
130 // Writes the last num_traces to the debugger output. | 143 // Writes the last num_traces to the debugger output. |
131 void DumpTrace(int num_traces) { | 144 void DumpTrace(int num_traces) { |
132 DCHECK(s_trace_buffer); | 145 DCHECK(s_trace_buffer); |
133 DebugOutput("Last traces:\n"); | 146 DebugOutput("Last traces:\n"); |
134 | 147 |
135 if (num_traces > kNumberOfEntries || num_traces < 0) | 148 if (num_traces > kNumberOfEntries || num_traces < 0) |
136 num_traces = kNumberOfEntries; | 149 num_traces = kNumberOfEntries; |
137 | 150 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 void DestroyTrace(void) { | 183 void DestroyTrace(void) { |
171 s_trace_object = NULL; | 184 s_trace_object = NULL; |
172 } | 185 } |
173 | 186 |
174 void Trace(const char* format, ...) { | 187 void Trace(const char* format, ...) { |
175 } | 188 } |
176 | 189 |
177 #endif // ENABLE_TRACING | 190 #endif // ENABLE_TRACING |
178 | 191 |
179 } // namespace disk_cache | 192 } // namespace disk_cache |
OLD | NEW |