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