1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/trace.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h>
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <windows.h>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Change this value to 1 to enable tracing on a release build. By default,
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// tracing is enabled only on debug builds.
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define ENABLE_TRACING 0
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#undef ENABLE_TRACING
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define ENABLE_TRACING 1
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kEntrySize = 48;
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kNumberOfEntries = 5000;  // 240 KB.
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct TraceBuffer {
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int num_traces;
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int current;
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char buffer[kNumberOfEntries][kEntrySize];
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if ENABLE_TRACING
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DebugOutput(const char* msg) {
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OutputDebugStringA(msg);
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  NOTIMPLEMENTED();
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif  // ENABLE_TRACING
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache {
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// s_trace_buffer and s_trace_object are not singletons because I want the
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// buffer to be destroyed and re-created when the last user goes away, and it
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// must be straightforward to access the buffer from the debugger.
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic TraceObject* s_trace_object = NULL;
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Static.
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTraceObject* TraceObject::GetTraceObject() {
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (s_trace_object)
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return s_trace_object;
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_object = new TraceObject();
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return s_trace_object;
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTraceObject::TraceObject() {
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  InitTrace();
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTraceObject::~TraceObject() {
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DestroyTrace();
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if ENABLE_TRACING
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic TraceBuffer* s_trace_buffer = NULL;
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid InitTrace(void) {
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (s_trace_buffer)
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_buffer = new TraceBuffer;
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memset(s_trace_buffer, 0, sizeof(*s_trace_buffer));
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DestroyTrace(void) {
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete s_trace_buffer;
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_buffer = NULL;
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_object = NULL;
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Trace(const char* format, ...) {
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!s_trace_buffer)
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  va_list ap;
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  va_start(ap, format);
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  vsprintf_s(s_trace_buffer->buffer[s_trace_buffer->current], format, ap);
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  vsnprintf(s_trace_buffer->buffer[s_trace_buffer->current],
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            sizeof(s_trace_buffer->buffer[s_trace_buffer->current]), format,
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            ap);
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_buffer->num_traces++;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_buffer->current++;
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (s_trace_buffer->current == kNumberOfEntries)
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    s_trace_buffer->current = 0;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  va_end(ap);
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Writes the last num_traces to the debugger output.
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DumpTrace(int num_traces) {
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(s_trace_buffer);
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DebugOutput("Last traces:\n");
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (num_traces > kNumberOfEntries || num_traces < 0)
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    num_traces = kNumberOfEntries;
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (s_trace_buffer->num_traces) {
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char line[kEntrySize + 2];
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int current = s_trace_buffer->current - num_traces;
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (current < 0)
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      current += kNumberOfEntries;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (int i = 0; i < num_traces; i++) {
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      memcpy(line, s_trace_buffer->buffer[current], kEntrySize);
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      line[kEntrySize] = '\0';
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      size_t length = strlen(line);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (length) {
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        line[length] = '\n';
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        line[length + 1] = '\0';
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        DebugOutput(line);
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      current++;
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (current ==  kNumberOfEntries)
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        current = 0;
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DebugOutput("End of Traces\n");
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else  // ENABLE_TRACING
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid InitTrace(void) {
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return;
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DestroyTrace(void) {
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  s_trace_object = NULL;
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Trace(const char* format, ...) {
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // ENABLE_TRACING
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace disk_cache
160