The second step towards merging the timer changes.

This patch does two things:

1. It overhalls the static initialization in Walltime to be simplier. It uses
   a static variable inside WallTime::Now() to initialize the timer.

2. Add a logging mechanism so that the -v flag actually has meaning and
   reimplement the CHECK macros to allow extra messages to be streamed in.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a5dc597..944c499 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 # Define the source files
 set(SOURCE_FILES "benchmark.cc" "colorprint.cc" "commandlineflags.cc"
-                 "sleep.cc" "sysinfo.cc" "walltime.cc")
+                 "log.cc" "sleep.cc" "sysinfo.cc" "walltime.cc")
 # Determine the correct regular expression engine to use
 if(HAVE_STD_REGEX)
   set(RE_FILES "re_std.cc")
diff --git a/src/benchmark.cc b/src/benchmark.cc
index 9b2d31b..97464c0 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -18,6 +18,7 @@
 #include "colorprint.h"
 #include "commandlineflags.h"
 #include "internal_macros.h"
+#include "log.h"
 #include "re.h"
 #include "sleep.h"
 #include "stat.h"
@@ -382,9 +383,7 @@
 
     // Match against filter.
     if (!re.Match(family->name_)) {
-#ifdef DEBUG
-      std::cout << "Skipping " << family->name_ << "\n";
-#endif
+      VLOG(1) << "Skipping " << family->name_ << "\n";
       continue;
     }
 
@@ -845,9 +844,7 @@
   }
   overhead = state.runs[0].real_accumulated_time /
              static_cast<double>(state.runs[0].iterations);
-#ifdef DEBUG
-  std::cout << "Per-iteration overhead for doing nothing: " << overhead << "\n";
-#endif
+  VLOG(1) << "Per-iteration overhead for doing nothing: " << overhead << "\n";
 }
 
 void Benchmark::RunInstance(const Instance& b, const BenchmarkReporter* br) {
@@ -1091,20 +1088,16 @@
 void State::NewInterval() {
   stop_time_micros_ = clock_->NowMicros() + interval_micros_;
   if (!is_continuation_) {
-#ifdef DEBUG
-    std::cout << "Starting new interval; stopping in " << interval_micros_
-              << "\n";
-#endif
+    VLOG(1) << "Starting new interval; stopping in " << interval_micros_
+            << "\n";
     iterations_ = 0;
     pause_cpu_time_ = 0;
     pause_real_time_ = 0;
     start_cpu_ = MyCPUUsage() + ChildrenCPUUsage();
     start_time_ = walltime::Now();
   } else {
-#ifdef DEBUG
-    std::cout << "Continuing interval; stopping in " << interval_micros_
-              << "\n";
-#endif
+    VLOG(1) << "Continuing interval; stopping in " << interval_micros_
+            << "\n";
   }
 }
 
@@ -1114,10 +1107,8 @@
            FLAGS_benchmark_iterations / FLAGS_benchmark_repetitions) ||
       iterations_ < 1) {
     interval_micros_ *= 2;
-#ifdef DEBUG
-    std::cout << "Not enough iterations in interval; "
-              << "Trying again for " << interval_micros_ << " useconds.\n";
-#endif
+    VLOG(1) << "Not enough iterations in interval; "
+            << "Trying again for " << interval_micros_ << " useconds.\n";
     is_continuation_ = false;
     NewInterval();
     return true;
@@ -1287,8 +1278,8 @@
 }
 
 void Initialize(int* argc, const char** argv) {
-  walltime::Initialize();
   internal::ParseCommandLineFlags(argc, argv);
+  internal::SetLogLevel(FLAGS_v);
   internal::Benchmark::MeasureOverhead();
 }
 
diff --git a/src/check.h b/src/check.h
index 6dd79cb..2b04cd2 100644
--- a/src/check.h
+++ b/src/check.h
@@ -1,12 +1,52 @@
 #ifndef CHECK_H_
 #define CHECK_H_
 
-#include <cassert>
+#include <cstdlib>
+#include <ostream>
 
-#define CHECK(b)             \
-  do {                       \
-    if (!(b)) assert(false); \
-  } while (0)
+#include "internal_macros.h"
+#include "log.h"
+
+namespace benchmark {
+namespace internal {
+
+// CheckHandler is the class constructed by failing CHECK macros. CheckHandler
+// will log information about the failures and abort when it is destructed.
+class CheckHandler {
+public:
+  CheckHandler(const char* check, const char* file, const char* func, int line)
+    : log_(GetErrorLogInstance())
+  {
+    log_ << file << ":" << line << ": " << func << ": Check `"
+          << check << "' failed. ";
+  }
+
+  std::ostream& GetLog() {
+    return log_;
+  }
+
+  BENCHMARK_NORETURN ~CheckHandler() {
+      log_ << std::endl;
+      std::abort();
+  }
+
+private:
+  std::ostream& log_;
+};
+
+} // end namespace internal
+} // end namespace benchmark
+
+// The CHECK macro returns a std::ostream object that can have extra information
+// written to it.
+#ifndef NDEBUG
+# define CHECK(b)  (b ? ::benchmark::internal::GetNullLogInstance()        \
+                      : ::benchmark::internal::CheckHandler(               \
+                          #b, __FILE__, __func__, __LINE__).GetLog())
+#else
+# define CHECK(b) ::benchmark::internal::GetNullLogInstance()
+#endif
+
 #define CHECK_EQ(a, b) CHECK((a) == (b))
 #define CHECK_NE(a, b) CHECK((a) != (b))
 #define CHECK_GE(a, b) CHECK((a) >= (b))
diff --git a/src/log.cc b/src/log.cc
new file mode 100644
index 0000000..b660309
--- /dev/null
+++ b/src/log.cc
@@ -0,0 +1,40 @@
+#include "log.h"
+
+#include <iostream>
+
+namespace benchmark {
+namespace internal {
+
+int& LoggingLevelImp() {
+    static int level = 0;
+    return level;
+}
+
+void SetLogLevel(int value) {
+    LoggingLevelImp() = value;
+}
+
+int GetLogLevel() {
+    return LoggingLevelImp();
+}
+
+class NullLogBuffer : public std::streambuf
+{
+public:
+  int overflow(int c) {
+    return c;
+  }
+};
+
+std::ostream& GetNullLogInstance() {
+  static NullLogBuffer log_buff;
+  static std::ostream null_log(&log_buff);
+  return null_log;
+}
+
+std::ostream& GetErrorLogInstance() {
+  return std::clog;
+}
+
+} // end namespace internal
+} // end namespace benchmark
\ No newline at end of file
diff --git a/src/log.h b/src/log.h
new file mode 100644
index 0000000..184ec4d
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,28 @@
+#ifndef BENCHMARK_LOG_H_
+#define BENCHMARK_LOG_H_
+
+#include <ostream>
+
+namespace benchmark {
+namespace internal {
+
+int GetLogLevel();
+void SetLogLevel(int level);
+
+std::ostream& GetNullLogInstance();
+std::ostream& GetErrorLogInstance();
+
+inline std::ostream& GetLogInstanceForLevel(int level) {
+  if (level >= GetLogLevel()) {
+    return GetErrorLogInstance();
+  }
+  return GetNullLogInstance();
+}
+
+} // end namespace internal
+} // end namespace benchmark
+
+#define VLOG(x) (::benchmark::internal::GetLogInstanceForLevel(x) \
+                 << "-- LOG(" << x << "): ")
+
+#endif
\ No newline at end of file
diff --git a/src/walltime.cc b/src/walltime.cc
index 8de4770..f4a1035 100644
--- a/src/walltime.cc
+++ b/src/walltime.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,14 +14,14 @@
 
 #include "walltime.h"
 
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
 #include <sys/time.h>
 #include <time.h>
-
+#include <cstdio>
+#include <cstdint>
+#include <cstring>
 #include <atomic>
 #include <limits>
+#include <type_traits>
 
 #include "check.h"
 #include "cycleclock.h"
@@ -30,44 +30,9 @@
 namespace benchmark {
 namespace walltime {
 namespace {
-const double kMaxErrorInterval = 100e-6;
 
-std::atomic<bool> initialized(false);
-WallTime base_walltime = 0.0;
-int64_t base_cycletime = 0;
-int64_t cycles_per_second;
-double seconds_per_cycle;
-uint32_t last_adjust_time = 0;
-std::atomic<int32_t> drift_adjust(0);
-int64_t max_interval_cycles = 0;
-
-// Helper routines to load/store a float from an AtomicWord. Required because
-// g++ < 4.7 doesn't support std::atomic<float> correctly. I cannot wait to get
-// rid of this horror show.
-inline void SetDrift(float f) {
-  int32_t w;
-  memcpy(&w, &f, sizeof(f));
-  std::atomic_store(&drift_adjust, w);
-}
-
-inline float GetDrift() {
-  float f;
-  int32_t w = std::atomic_load(&drift_adjust);
-  memcpy(&f, &w, sizeof(f));
-  return f;
-}
-
-static_assert(sizeof(float) <= sizeof(int32_t),
-              "type sizes don't allow the drift_adjust hack");
-
-WallTime Slow() {
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  return tv.tv_sec + tv.tv_usec * 1e-6;
-}
-
-bool SplitTimezone(WallTime value, bool local, struct tm* t,
-                   double* subsecond) {
+inline bool SplitTimezone(WallTime value, bool local, struct tm* t,
+                             double* subsecond) {
   memset(t, 0, sizeof(*t));
   if ((value < 0) || (value > std::numeric_limits<time_t>::max())) {
     *subsecond = 0.0;
@@ -81,58 +46,127 @@
     gmtime_r(&whole_time, t);
   return true;
 }
-}  // end namespace
 
-// This routine should be invoked to initialize walltime.
-// It is not intended for general purpose use.
-void Initialize() {
-  CHECK(!std::atomic_load(&initialized));
-  cycles_per_second = static_cast<int64_t>(CyclesPerSecond());
-  CHECK(cycles_per_second != 0);
-  seconds_per_cycle = 1.0 / cycles_per_second;
-  max_interval_cycles =
-      static_cast<int64_t>(cycles_per_second * kMaxErrorInterval);
-  do {
-    base_cycletime = cycleclock::Now();
-    base_walltime = Slow();
-  } while (cycleclock::Now() - base_cycletime > max_interval_cycles);
-  // We are now sure that "base_walltime" and "base_cycletime" were produced
-  // within kMaxErrorInterval of one another.
+} // end anonymous namespace
 
-  SetDrift(0.0);
-  last_adjust_time = static_cast<uint32_t>(uint64_t(base_cycletime) >> 32);
-  std::atomic_store(&initialized, true);
-}
 
-WallTime Now() {
-  if (!std::atomic_load(&initialized)) return Slow();
+namespace internal {
 
+class WallTimeImp
+{
+public:
+  WallTime Now();
+
+  static WallTimeImp & GetWallTimeImp() {
+    static WallTimeImp imp;
+#if __cplusplus >= 201103L
+    static_assert(std::is_trivially_destructible<WallTimeImp>::value,
+                  "WallTimeImp must be trivially destructible to prevent "
+                  "issues with static destruction");
+#endif
+    return imp;
+  }
+
+private:
+  WallTimeImp();
+  // Helper routines to load/store a float from an AtomicWord. Required because
+  // g++ < 4.7 doesn't support std::atomic<float> correctly. I cannot wait to
+  // get rid of this horror show.
+  void SetDrift(float f) {
+    int32_t w;
+    memcpy(&w, &f, sizeof(f));
+    std::atomic_store(&drift_adjust_, w);
+  }
+
+  float GetDrift() const {
+    float f;
+    int32_t w = std::atomic_load(&drift_adjust_);
+    memcpy(&f, &w, sizeof(f));
+    return f;
+  }
+
+  WallTime Slow() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec + tv.tv_usec * 1e-6;
+  }
+
+private:
+  static_assert(sizeof(float) <= sizeof(int32_t),
+               "type sizes don't allow the drift_adjust hack");
+
+  static constexpr double kMaxErrorInterval = 100e-6;
+
+  WallTime base_walltime_;
+  int64_t base_cycletime_;
+  int64_t cycles_per_second_;
+  double seconds_per_cycle_;
+  uint32_t last_adjust_time_;
+  std::atomic<int32_t> drift_adjust_;
+  int64_t max_interval_cycles_;
+
+  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(WallTimeImp);
+};
+
+
+WallTime WallTimeImp::Now() {
   WallTime now = 0.0;
   WallTime result = 0.0;
   int64_t ct = 0;
   uint32_t top_bits = 0;
   do {
     ct = cycleclock::Now();
-    int64_t cycle_delta = ct - base_cycletime;
-    result = base_walltime + cycle_delta * seconds_per_cycle;
+    int64_t cycle_delta = ct - base_cycletime_;
+    result = base_walltime_ + cycle_delta * seconds_per_cycle_;
 
     top_bits = static_cast<uint32_t>(uint64_t(ct) >> 32);
     // Recompute drift no more often than every 2^32 cycles.
     // I.e., @2GHz, ~ every two seconds
-    if (top_bits == last_adjust_time) {  // don't need to recompute drift
+    if (top_bits == last_adjust_time_) {  // don't need to recompute drift
       return result + GetDrift();
     }
 
     now = Slow();
-  } while (cycleclock::Now() - ct > max_interval_cycles);
+  } while (cycleclock::Now() - ct > max_interval_cycles_);
   // We are now sure that "now" and "result" were produced within
   // kMaxErrorInterval of one another.
 
   SetDrift(now - result);
-  last_adjust_time = top_bits;
+  last_adjust_time_ = top_bits;
   return now;
 }
 
+
+WallTimeImp::WallTimeImp()
+    : base_walltime_(0.0), base_cycletime_(0),
+      cycles_per_second_(0), seconds_per_cycle_(0.0),
+      last_adjust_time_(0), drift_adjust_(0),
+      max_interval_cycles_(0) {
+  cycles_per_second_ = static_cast<int64_t>(CyclesPerSecond());
+  CHECK(cycles_per_second_ != 0);
+  seconds_per_cycle_ = 1.0 / cycles_per_second_;
+  max_interval_cycles_ =
+      static_cast<int64_t>(cycles_per_second_ * kMaxErrorInterval);
+  do {
+    base_cycletime_ = cycleclock::Now();
+    base_walltime_ = Slow();
+  } while (cycleclock::Now() - base_cycletime_ > max_interval_cycles_);
+  // We are now sure that "base_walltime" and "base_cycletime" were produced
+  // within kMaxErrorInterval of one another.
+
+  SetDrift(0.0);
+  last_adjust_time_ = static_cast<uint32_t>(uint64_t(base_cycletime_) >> 32);
+}
+
+} // end namespace internal
+
+
+WallTime Now()
+{
+    static internal::WallTimeImp& imp = internal::WallTimeImp::GetWallTimeImp();
+    return imp.Now();
+}
+
 std::string Print(WallTime time, const char* format, bool local,
                   int* remainder_us) {
   char storage[32];
@@ -150,5 +184,6 @@
   }
   return std::string(storage);
 }
+
 }  // end namespace walltime
 }  // end namespace benchmark
diff --git a/src/walltime.h b/src/walltime.h
index 7d34ddf..d4a4fce 100644
--- a/src/walltime.h
+++ b/src/walltime.h
@@ -7,7 +7,6 @@
 typedef double WallTime;
 
 namespace walltime {
-void Initialize();
 WallTime Now();
 
 // GIVEN: walltime, generic format string (as understood by strftime),
diff --git a/test/benchmark_test.cc b/test/benchmark_test.cc
index cade774..3c2eeed 100644
--- a/test/benchmark_test.cc
+++ b/test/benchmark_test.cc
@@ -24,7 +24,7 @@
 
 namespace {
 
-#ifdef DEBUG
+#ifndef NDEBUG
 int BENCHMARK_NOINLINE Factorial(uint32_t n) {
   return (n == 1) ? 1 : n * Factorial(n - 1);
 }
@@ -52,7 +52,7 @@
 
 }  // end namespace
 
-#ifdef DEBUG
+#ifndef NDEBUG
 static void BM_Factorial(benchmark::State& state) {
   int fac_42 = 0;
   while (state.KeepRunning())
@@ -179,7 +179,7 @@
 int main(int argc, const char* argv[]) {
   benchmark::Initialize(&argc, argv);
 
-#ifdef DEBUG
+#ifndef NDEBUG
   assert(Factorial(8) == 40320);
 #endif
   assert(CalculatePi(1) == 0.0);