Commit 332f677b by Dominic Hamon Committed by GitHub

Apply clang-format to all headers and source (#303)

parent 1100e919
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#ifndef BENCHMARK_BENCHMARK_H_ #ifndef BENCHMARK_BENCHMARK_H_
#define BENCHMARK_BENCHMARK_H_ #define BENCHMARK_BENCHMARK_H_
#include "macros.h"
#include "benchmark_api.h" #include "benchmark_api.h"
#include "macros.h"
#include "reporter.h" #include "reporter.h"
#endif // BENCHMARK_BENCHMARK_H_ #endif // BENCHMARK_BENCHMARK_H_
...@@ -19,44 +19,44 @@ ...@@ -19,44 +19,44 @@
#endif #endif
#ifndef BENCHMARK_HAS_CXX11 #ifndef BENCHMARK_HAS_CXX11
# define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ #define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \ TypeName(const TypeName&); \
TypeName& operator=(const TypeName&) TypeName& operator=(const TypeName&)
#else #else
# define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ #define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \ TypeName(const TypeName&) = delete; \
TypeName& operator=(const TypeName&) = delete TypeName& operator=(const TypeName&) = delete
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
# define BENCHMARK_UNUSED __attribute__((unused)) #define BENCHMARK_UNUSED __attribute__((unused))
# define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline)) #define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
# define BENCHMARK_NOEXCEPT noexcept #define BENCHMARK_NOEXCEPT noexcept
# define BENCHMARK_NOEXCEPT_OP(x) noexcept(x) #define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
#elif defined(_MSC_VER) && !defined(__clang__) #elif defined(_MSC_VER) && !defined(__clang__)
# define BENCHMARK_UNUSED #define BENCHMARK_UNUSED
# define BENCHMARK_ALWAYS_INLINE __forceinline #define BENCHMARK_ALWAYS_INLINE __forceinline
# if _MSC_VER >= 1900 #if _MSC_VER >= 1900
# define BENCHMARK_NOEXCEPT noexcept #define BENCHMARK_NOEXCEPT noexcept
# define BENCHMARK_NOEXCEPT_OP(x) noexcept(x) #define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
# else
# define BENCHMARK_NOEXCEPT
# define BENCHMARK_NOEXCEPT_OP(x)
# endif
# define __func__ __FUNCTION__
#else #else
# define BENCHMARK_UNUSED #define BENCHMARK_NOEXCEPT
# define BENCHMARK_ALWAYS_INLINE #define BENCHMARK_NOEXCEPT_OP(x)
# define BENCHMARK_NOEXCEPT #endif
# define BENCHMARK_NOEXCEPT_OP(x) #define __func__ __FUNCTION__
#else
#define BENCHMARK_UNUSED
#define BENCHMARK_ALWAYS_INLINE
#define BENCHMARK_NOEXCEPT
#define BENCHMARK_NOEXCEPT_OP(x)
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
# define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y) #define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
# define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) #define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
#else #else
# define BENCHMARK_BUILTIN_EXPECT(x, y) x #define BENCHMARK_BUILTIN_EXPECT(x, y) x
# define BENCHMARK_DEPRECATED_MSG(msg) #define BENCHMARK_DEPRECATED_MSG(msg)
#endif #endif
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
......
...@@ -41,20 +41,20 @@ class BenchmarkReporter { ...@@ -41,20 +41,20 @@ class BenchmarkReporter {
}; };
struct Run { struct Run {
Run() : Run()
error_occurred(false), : error_occurred(false),
iterations(1), iterations(1),
time_unit(kNanosecond), time_unit(kNanosecond),
real_accumulated_time(0), real_accumulated_time(0),
cpu_accumulated_time(0), cpu_accumulated_time(0),
bytes_per_second(0), bytes_per_second(0),
items_per_second(0), items_per_second(0),
max_heapbytes_used(0), max_heapbytes_used(0),
complexity(oNone), complexity(oNone),
complexity_lambda(), complexity_lambda(),
complexity_n(0), complexity_n(0),
report_big_o(false), report_big_o(false),
report_rms(false) {} report_rms(false) {}
std::string benchmark_name; std::string benchmark_name;
std::string report_label; // Empty if not set by benchmark. std::string report_label; // Empty if not set by benchmark.
...@@ -134,13 +134,9 @@ class BenchmarkReporter { ...@@ -134,13 +134,9 @@ class BenchmarkReporter {
error_stream_ = err; error_stream_ = err;
} }
std::ostream& GetOutputStream() const { std::ostream& GetOutputStream() const { return *output_stream_; }
return *output_stream_;
}
std::ostream& GetErrorStream() const { std::ostream& GetErrorStream() const { return *error_stream_; }
return *error_stream_;
}
virtual ~BenchmarkReporter(); virtual ~BenchmarkReporter();
...@@ -157,22 +153,19 @@ class BenchmarkReporter { ...@@ -157,22 +153,19 @@ class BenchmarkReporter {
// Simple reporter that outputs benchmark data to the console. This is the // Simple reporter that outputs benchmark data to the console. This is the
// default reporter used by RunSpecifiedBenchmarks(). // default reporter used by RunSpecifiedBenchmarks().
class ConsoleReporter : public BenchmarkReporter { class ConsoleReporter : public BenchmarkReporter {
public: public:
enum OutputOptions { enum OutputOptions { OO_None, OO_Color };
OO_None,
OO_Color
};
explicit ConsoleReporter(OutputOptions color_output = OO_Color) explicit ConsoleReporter(OutputOptions color_output = OO_Color)
: name_field_width_(0), color_output_(color_output == OO_Color) {} : name_field_width_(0), color_output_(color_output == OO_Color) {}
virtual bool ReportContext(const Context& context); virtual bool ReportContext(const Context& context);
virtual void ReportRuns(const std::vector<Run>& reports); virtual void ReportRuns(const std::vector<Run>& reports);
protected: protected:
virtual void PrintRunData(const Run& report); virtual void PrintRunData(const Run& report);
size_t name_field_width_; size_t name_field_width_;
private: private:
bool color_output_; bool color_output_;
}; };
......
...@@ -11,7 +11,6 @@ namespace internal { ...@@ -11,7 +11,6 @@ namespace internal {
// a pointer by mistake, you will get a compile-time error. // a pointer by mistake, you will get a compile-time error.
// //
// This template function declaration is used in defining arraysize. // This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only // Note that the function doesn't need an implementation, as we only
// use its type. // use its type.
...@@ -28,7 +27,7 @@ char (&ArraySizeHelper(const T (&array)[N]))[N]; ...@@ -28,7 +27,7 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
#define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array))) #define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array)))
} // end namespace internal } // end namespace internal
} // end namespace benchmark } // end namespace benchmark
#endif // BENCHMARK_ARRAYSIZE_H_ #endif // BENCHMARK_ARRAYSIZE_H_
...@@ -3,44 +3,45 @@ ...@@ -3,44 +3,45 @@
#include "benchmark/benchmark_api.h" #include "benchmark/benchmark_api.h"
#include <string>
#include <vector>
#include <limits>
#include <cmath> #include <cmath>
#include <iosfwd> #include <iosfwd>
#include <limits>
#include <string>
#include <vector>
namespace benchmark { namespace benchmark {
namespace internal { namespace internal {
// Information kept per benchmark we may want to run // Information kept per benchmark we may want to run
struct Benchmark::Instance { struct Benchmark::Instance {
std::string name; std::string name;
Benchmark* benchmark; Benchmark* benchmark;
ReportMode report_mode; ReportMode report_mode;
std::vector<int> arg; std::vector<int> arg;
TimeUnit time_unit; TimeUnit time_unit;
int range_multiplier; int range_multiplier;
bool use_real_time; bool use_real_time;
bool use_manual_time; bool use_manual_time;
BigO complexity; BigO complexity;
BigOFunc* complexity_lambda; BigOFunc* complexity_lambda;
bool last_benchmark_instance; bool last_benchmark_instance;
int repetitions; int repetitions;
double min_time; double min_time;
int threads; // Number of concurrent threads to us int threads; // Number of concurrent threads to us
}; };
bool FindBenchmarksInternal(const std::string& re, bool FindBenchmarksInternal(const std::string& re,
std::vector<Benchmark::Instance>* benchmarks, std::ostream* Err); std::vector<Benchmark::Instance>* benchmarks,
std::ostream* Err);
namespace { namespace {
bool IsZero(double n) { bool IsZero(double n) {
return std::abs(n) < std::numeric_limits<double>::epsilon(); return std::abs(n) < std::numeric_limits<double>::epsilon();
} }
} // end namespace } // end namespace
} // end namespace internal } // end namespace internal
} // end namespace benchmark } // end namespace benchmark
#endif // BENCHMARK_API_INTERNAL_H #endif // BENCHMARK_API_INTERNAL_H
...@@ -13,23 +13,23 @@ ...@@ -13,23 +13,23 @@
// limitations under the License. // limitations under the License.
#include "benchmark/benchmark.h" #include "benchmark/benchmark.h"
#include "internal_macros.h"
#include "benchmark_api_internal.h" #include "benchmark_api_internal.h"
#include "internal_macros.h"
#ifndef BENCHMARK_OS_WINDOWS #ifndef BENCHMARK_OS_WINDOWS
#include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <iostream> #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream> #include <fstream>
#include <iostream>
#include <memory> #include <memory>
#include <thread> #include <thread>
...@@ -74,6 +74,7 @@ class BenchmarkFamilies { ...@@ -74,6 +74,7 @@ class BenchmarkFamilies {
bool FindBenchmarks(const std::string& re, bool FindBenchmarks(const std::string& re,
std::vector<Benchmark::Instance>* benchmarks, std::vector<Benchmark::Instance>* benchmarks,
std::ostream* Err); std::ostream* Err);
private: private:
BenchmarkFamilies() {} BenchmarkFamilies() {}
...@@ -94,8 +95,7 @@ size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) { ...@@ -94,8 +95,7 @@ size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
} }
bool BenchmarkFamilies::FindBenchmarks( bool BenchmarkFamilies::FindBenchmarks(
const std::string& spec, const std::string& spec, std::vector<Benchmark::Instance>* benchmarks,
std::vector<Benchmark::Instance>* benchmarks,
std::ostream* ErrStream) { std::ostream* ErrStream) {
CHECK(ErrStream); CHECK(ErrStream);
auto& Err = *ErrStream; auto& Err = *ErrStream;
...@@ -120,23 +120,21 @@ bool BenchmarkFamilies::FindBenchmarks( ...@@ -120,23 +120,21 @@ bool BenchmarkFamilies::FindBenchmarks(
} }
const std::vector<int>* thread_counts = const std::vector<int>* thread_counts =
(family->thread_counts_.empty() (family->thread_counts_.empty()
? &one_thread ? &one_thread
: &static_cast<const std::vector<int>&>(family->thread_counts_)); : &static_cast<const std::vector<int>&>(family->thread_counts_));
const size_t family_size = family->args_.size() * thread_counts->size(); const size_t family_size = family->args_.size() * thread_counts->size();
// The benchmark will be run at least 'family_size' different inputs. // The benchmark will be run at least 'family_size' different inputs.
// If 'family_size' is very large warn the user. // If 'family_size' is very large warn the user.
if (family_size > kMaxFamilySize) { if (family_size > kMaxFamilySize) {
Err << "The number of inputs is very large. " << family->name_ Err << "The number of inputs is very large. " << family->name_
<< " will be repeated at least " << family_size << " times.\n"; << " will be repeated at least " << family_size << " times.\n";
} }
// reserve in the special case the regex ".", since we know the final // reserve in the special case the regex ".", since we know the final
// family size. // family size.
if (spec == ".") if (spec == ".") benchmarks->reserve(family_size);
benchmarks->reserve(family_size);
for (auto const& args : family->args_) { for (auto const& args : family->args_) {
for (int num_threads : *thread_counts) { for (int num_threads : *thread_counts) {
Benchmark::Instance instance; Benchmark::Instance instance;
instance.name = family->name_; instance.name = family->name_;
instance.benchmark = family.get(); instance.benchmark = family.get();
...@@ -158,15 +156,15 @@ bool BenchmarkFamilies::FindBenchmarks( ...@@ -158,15 +156,15 @@ bool BenchmarkFamilies::FindBenchmarks(
} }
if (!IsZero(family->min_time_)) { if (!IsZero(family->min_time_)) {
instance.name += StringPrintF("/min_time:%0.3f", family->min_time_); instance.name += StringPrintF("/min_time:%0.3f", family->min_time_);
} }
if (family->repetitions_ != 0) { if (family->repetitions_ != 0) {
instance.name += StringPrintF("/repeats:%d", family->repetitions_); instance.name += StringPrintF("/repeats:%d", family->repetitions_);
} }
if (family->use_manual_time_) { if (family->use_manual_time_) {
instance.name += "/manual_time"; instance.name += "/manual_time";
} else if (family->use_real_time_) { } else if (family->use_real_time_) {
instance.name += "/real_time"; instance.name += "/real_time";
} }
// Add the number of threads used to the name // Add the number of threads used to the name
...@@ -185,37 +183,37 @@ bool BenchmarkFamilies::FindBenchmarks( ...@@ -185,37 +183,37 @@ bool BenchmarkFamilies::FindBenchmarks(
} }
Benchmark* RegisterBenchmarkInternal(Benchmark* bench) { Benchmark* RegisterBenchmarkInternal(Benchmark* bench) {
std::unique_ptr<Benchmark> bench_ptr(bench); std::unique_ptr<Benchmark> bench_ptr(bench);
BenchmarkFamilies* families = BenchmarkFamilies::GetInstance(); BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();
families->AddBenchmark(std::move(bench_ptr)); families->AddBenchmark(std::move(bench_ptr));
return bench; return bench;
} }
// FIXME: This function is a hack so that benchmark.cc can access // FIXME: This function is a hack so that benchmark.cc can access
// `BenchmarkFamilies` // `BenchmarkFamilies`
bool FindBenchmarksInternal(const std::string& re, bool FindBenchmarksInternal(const std::string& re,
std::vector<Benchmark::Instance>* benchmarks, std::vector<Benchmark::Instance>* benchmarks,
std::ostream* Err) std::ostream* Err) {
{
return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err); return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
} }
//=============================================================================// //=============================================================================//
// Benchmark // Benchmark
//=============================================================================// //=============================================================================//
Benchmark::Benchmark(const char* name) Benchmark::Benchmark(const char* name)
: name_(name), report_mode_(RM_Unspecified), : name_(name),
time_unit_(kNanosecond), range_multiplier_(kRangeMultiplier), report_mode_(RM_Unspecified),
min_time_(0), repetitions_(0), use_real_time_(false), time_unit_(kNanosecond),
use_manual_time_(false), complexity_(oNone), complexity_lambda_(nullptr) range_multiplier_(kRangeMultiplier),
{ min_time_(0),
} repetitions_(0),
use_real_time_(false),
Benchmark::~Benchmark() { use_manual_time_(false),
} complexity_(oNone),
complexity_lambda_(nullptr) {}
Benchmark::~Benchmark() {}
void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) { void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) {
CHECK_GE(lo, 0); CHECK_GE(lo, 0);
...@@ -228,7 +226,7 @@ void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) { ...@@ -228,7 +226,7 @@ void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) {
static const int kint32max = std::numeric_limits<int32_t>::max(); static const int kint32max = std::numeric_limits<int32_t>::max();
// Now space out the benchmarks in multiples of "mult" // Now space out the benchmarks in multiples of "mult"
for (int32_t i = 1; i < kint32max/mult; i *= mult) { for (int32_t i = 1; i < kint32max / mult; i *= mult) {
if (i >= hi) break; if (i >= hi) break;
if (i > lo) { if (i > lo) {
dst->push_back(i); dst->push_back(i);
...@@ -262,13 +260,13 @@ Benchmark* Benchmark::Range(int start, int limit) { ...@@ -262,13 +260,13 @@ Benchmark* Benchmark::Range(int start, int limit) {
return this; return this;
} }
Benchmark* Benchmark::Ranges(const std::vector<std::pair<int, int>>& ranges) Benchmark* Benchmark::Ranges(const std::vector<std::pair<int, int>>& ranges) {
{
CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size())); CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
std::vector<std::vector<int>> arglists(ranges.size()); std::vector<std::vector<int>> arglists(ranges.size());
std::size_t total = 1; std::size_t total = 1;
for (std::size_t i = 0; i < ranges.size(); i++) { for (std::size_t i = 0; i < ranges.size(); i++) {
AddRange(&arglists[i], ranges[i].first, ranges[i].second, range_multiplier_); AddRange(&arglists[i], ranges[i].first, ranges[i].second,
range_multiplier_);
total *= arglists[i].size(); total *= arglists[i].size();
} }
...@@ -299,7 +297,7 @@ Benchmark* Benchmark::DenseRange(int start, int limit, int step) { ...@@ -299,7 +297,7 @@ Benchmark* Benchmark::DenseRange(int start, int limit, int step) {
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
CHECK_GE(start, 0); CHECK_GE(start, 0);
CHECK_LE(start, limit); CHECK_LE(start, limit);
for (int arg = start; arg <= limit; arg+= step) { for (int arg = start; arg <= limit; arg += step) {
args_.push_back({arg}); args_.push_back({arg});
} }
return this; return this;
...@@ -340,13 +338,15 @@ Benchmark* Benchmark::MinTime(double t) { ...@@ -340,13 +338,15 @@ Benchmark* Benchmark::MinTime(double t) {
} }
Benchmark* Benchmark::UseRealTime() { Benchmark* Benchmark::UseRealTime() {
CHECK(!use_manual_time_) << "Cannot set UseRealTime and UseManualTime simultaneously."; CHECK(!use_manual_time_)
<< "Cannot set UseRealTime and UseManualTime simultaneously.";
use_real_time_ = true; use_real_time_ = true;
return this; return this;
} }
Benchmark* Benchmark::UseManualTime() { Benchmark* Benchmark::UseManualTime() {
CHECK(!use_real_time_) << "Cannot set UseRealTime and UseManualTime simultaneously."; CHECK(!use_real_time_)
<< "Cannot set UseRealTime and UseManualTime simultaneously.";
use_manual_time_ = true; use_manual_time_ = true;
return this; return this;
} }
...@@ -376,7 +376,7 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) { ...@@ -376,7 +376,7 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
return this; return this;
} }
Benchmark *Benchmark::DenseThreadRange(int min_threads, int max_threads, Benchmark* Benchmark::DenseThreadRange(int min_threads, int max_threads,
int stride) { int stride) {
CHECK_GT(min_threads, 0); CHECK_GT(min_threads, 0);
CHECK_GE(max_threads, min_threads); CHECK_GE(max_threads, min_threads);
...@@ -395,21 +395,17 @@ Benchmark* Benchmark::ThreadPerCpu() { ...@@ -395,21 +395,17 @@ Benchmark* Benchmark::ThreadPerCpu() {
return this; return this;
} }
void Benchmark::SetName(const char* name) { void Benchmark::SetName(const char* name) { name_ = name; }
name_ = name;
}
int Benchmark::ArgsCnt() const
{ return args_.empty() ? -1 : static_cast<int>(args_.front().size()); }
int Benchmark::ArgsCnt() const {
return args_.empty() ? -1 : static_cast<int>(args_.front().size());
}
//=============================================================================// //=============================================================================//
// FunctionBenchmark // FunctionBenchmark
//=============================================================================// //=============================================================================//
void FunctionBenchmark::Run(State& st) { void FunctionBenchmark::Run(State& st) { func_(st); }
func_(st);
}
} // end namespace internal } // end namespace internal
} // end namespace benchmark } // end namespace benchmark
...@@ -13,51 +13,52 @@ namespace internal { ...@@ -13,51 +13,52 @@ namespace internal {
typedef void(AbortHandlerT)(); typedef void(AbortHandlerT)();
inline AbortHandlerT*& GetAbortHandler() { inline AbortHandlerT*& GetAbortHandler() {
static AbortHandlerT* handler = &std::abort; static AbortHandlerT* handler = &std::abort;
return handler; return handler;
} }
BENCHMARK_NORETURN inline void CallAbortHandler() { BENCHMARK_NORETURN inline void CallAbortHandler() {
GetAbortHandler()(); GetAbortHandler()();
std::abort(); // fallback to enforce noreturn std::abort(); // fallback to enforce noreturn
} }
// CheckHandler is the class constructed by failing CHECK macros. CheckHandler // CheckHandler is the class constructed by failing CHECK macros. CheckHandler
// will log information about the failures and abort when it is destructed. // will log information about the failures and abort when it is destructed.
class CheckHandler { class CheckHandler {
public: public:
CheckHandler(const char* check, const char* file, const char* func, int line) CheckHandler(const char* check, const char* file, const char* func, int line)
: log_(GetErrorLogInstance()) : log_(GetErrorLogInstance()) {
{ log_ << file << ":" << line << ": " << func << ": Check `" << check
log_ << file << ":" << line << ": " << func << ": Check `" << "' failed. ";
<< check << "' failed. ";
} }
LogType& GetLog() { return log_; } LogType& GetLog() { return log_; }
BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) { BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
log_ << std::endl; log_ << std::endl;
CallAbortHandler(); CallAbortHandler();
} }
CheckHandler & operator=(const CheckHandler&) = delete; CheckHandler& operator=(const CheckHandler&) = delete;
CheckHandler(const CheckHandler&) = delete; CheckHandler(const CheckHandler&) = delete;
CheckHandler() = delete; CheckHandler() = delete;
private:
LogType& log_; private:
LogType& log_;
}; };
} // end namespace internal } // end namespace internal
} // end namespace benchmark } // end namespace benchmark
// The CHECK macro returns a std::ostream object that can have extra information // The CHECK macro returns a std::ostream object that can have extra information
// written to it. // written to it.
#ifndef NDEBUG #ifndef NDEBUG
# define CHECK(b) (b ? ::benchmark::internal::GetNullLogInstance() \ #define CHECK(b) \
: ::benchmark::internal::CheckHandler( \ (b ? ::benchmark::internal::GetNullLogInstance() \
#b, __FILE__, __func__, __LINE__).GetLog()) : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \
.GetLog())
#else #else
# define CHECK(b) ::benchmark::internal::GetNullLogInstance() #define CHECK(b) ::benchmark::internal::GetNullLogInstance()
#endif #endif
#define CHECK_EQ(a, b) CHECK((a) == (b)) #define CHECK_EQ(a, b) CHECK((a) == (b))
......
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
#include "internal_macros.h" #include "internal_macros.h"
#ifdef BENCHMARK_OS_WINDOWS #ifdef BENCHMARK_OS_WINDOWS
#include <io.h>
#include <Windows.h> #include <Windows.h>
#include <io.h>
#else #else
#include <unistd.h> #include <unistd.h>
#endif // BENCHMARK_OS_WINDOWS #endif // BENCHMARK_OS_WINDOWS
namespace benchmark { namespace benchmark {
namespace { namespace {
...@@ -82,7 +82,7 @@ PlatformColorCode GetPlatformColorCode(LogColor color) { ...@@ -82,7 +82,7 @@ PlatformColorCode GetPlatformColorCode(LogColor color) {
} // end namespace } // end namespace
std::string FormatString(const char *msg, va_list args) { std::string FormatString(const char* msg, va_list args) {
// we might need a second shot at this, so pre-emptivly make a copy // we might need a second shot at this, so pre-emptivly make a copy
va_list args_cp; va_list args_cp;
va_copy(args_cp, args); va_copy(args_cp, args);
...@@ -96,13 +96,13 @@ std::string FormatString(const char *msg, va_list args) { ...@@ -96,13 +96,13 @@ std::string FormatString(const char *msg, va_list args) {
// currently there is no error handling for failure, so this is hack. // currently there is no error handling for failure, so this is hack.
CHECK(ret >= 0); CHECK(ret >= 0);
if (ret == 0) // handle empty expansion if (ret == 0) // handle empty expansion
return {}; return {};
else if (static_cast<size_t>(ret) < size) else if (static_cast<size_t>(ret) < size)
return local_buff; return local_buff;
else { else {
// we did not provide a long enough buffer on our first attempt. // we did not provide a long enough buffer on our first attempt.
size = (size_t)ret + 1; // + 1 for the null byte size = (size_t)ret + 1; // + 1 for the null byte
std::unique_ptr<char[]> buff(new char[size]); std::unique_ptr<char[]> buff(new char[size]);
ret = std::vsnprintf(buff.get(), size, msg, args); ret = std::vsnprintf(buff.get(), size, msg, args);
CHECK(ret > 0 && ((size_t)ret) < size); CHECK(ret > 0 && ((size_t)ret) < size);
...@@ -110,7 +110,7 @@ std::string FormatString(const char *msg, va_list args) { ...@@ -110,7 +110,7 @@ std::string FormatString(const char *msg, va_list args) {
} }
} }
std::string FormatString(const char *msg, ...) { std::string FormatString(const char* msg, ...) {
va_list args; va_list args;
va_start(args, msg); va_start(args, msg);
auto tmp = FormatString(msg, args); auto tmp = FormatString(msg, args);
...@@ -125,9 +125,10 @@ void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) { ...@@ -125,9 +125,10 @@ void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) {
va_end(args); va_end(args);
} }
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, va_list args) { void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
va_list args) {
#ifdef BENCHMARK_OS_WINDOWS #ifdef BENCHMARK_OS_WINDOWS
((void)out); // suppress unused warning ((void)out); // suppress unused warning
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
...@@ -152,7 +153,6 @@ void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, va_list arg ...@@ -152,7 +153,6 @@ void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, va_list arg
if (color_code) out << FormatString("\033[0;3%sm", color_code); if (color_code) out << FormatString("\033[0;3%sm", color_code);
out << FormatString(fmt, args) << "\033[m"; out << FormatString(fmt, args) << "\033[m";
#endif #endif
} }
bool IsColorTerminal() { bool IsColorTerminal() {
...@@ -182,7 +182,7 @@ bool IsColorTerminal() { ...@@ -182,7 +182,7 @@ bool IsColorTerminal() {
} }
return 0 != isatty(fileno(stdout)) && term_supports_color; return 0 != isatty(fileno(stdout)) && term_supports_color;
#endif // BENCHMARK_OS_WINDOWS #endif // BENCHMARK_OS_WINDOWS
} }
} // end namespace benchmark } // end namespace benchmark
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
#define BENCHMARK_COLORPRINT_H_ #define BENCHMARK_COLORPRINT_H_
#include <cstdarg> #include <cstdarg>
#include <string>
#include <iostream> #include <iostream>
#include <string>
namespace benchmark { namespace benchmark {
enum LogColor { enum LogColor {
...@@ -20,7 +20,8 @@ enum LogColor { ...@@ -20,7 +20,8 @@ enum LogColor {
std::string FormatString(const char* msg, va_list args); std::string FormatString(const char* msg, va_list args);
std::string FormatString(const char* msg, ...); std::string FormatString(const char* msg, ...);
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, va_list args); void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
va_list args);
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...); void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);
// Returns true if stdout appears to be a terminal that supports colored // Returns true if stdout appears to be a terminal that supports colored
......
...@@ -44,7 +44,7 @@ bool ParseInt32(const std::string& src_text, const char* str, int32_t* value) { ...@@ -44,7 +44,7 @@ bool ParseInt32(const std::string& src_text, const char* str, int32_t* value) {
// The parsed value overflows as a long. (strtol() returns // The parsed value overflows as a long. (strtol() returns
// LONG_MAX or LONG_MIN when the input overflows.) // LONG_MAX or LONG_MIN when the input overflows.)
result != long_value result != long_value
// The parsed value overflows as an Int32. // The parsed value overflows as an Int32.
) { ) {
std::cerr << src_text << " is expected to be a 32-bit integer, " std::cerr << src_text << " is expected to be a 32-bit integer, "
<< "but actually has value \"" << str << "\", " << "but actually has value \"" << str << "\", "
...@@ -95,7 +95,8 @@ static std::string FlagToEnvVar(const char* flag) { ...@@ -95,7 +95,8 @@ static std::string FlagToEnvVar(const char* flag) {
bool BoolFromEnv(const char* flag, bool default_value) { bool BoolFromEnv(const char* flag, bool default_value) {
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = getenv(env_var.c_str()); const char* const string_value = getenv(env_var.c_str());
return string_value == nullptr ? default_value : strcmp(string_value, "0") != 0; return string_value == nullptr ? default_value
: strcmp(string_value, "0") != 0;
} }
// Reads and returns a 32-bit integer stored in the environment // Reads and returns a 32-bit integer stored in the environment
...@@ -209,8 +210,7 @@ bool IsFlag(const char* str, const char* flag) { ...@@ -209,8 +210,7 @@ bool IsFlag(const char* str, const char* flag) {
} }
bool IsTruthyFlagValue(const std::string& str) { bool IsTruthyFlagValue(const std::string& str) {
if (str.empty()) if (str.empty()) return true;
return true;
char ch = str[0]; char ch = str[0];
return isalnum(ch) && return isalnum(ch) &&
!(ch == '0' || ch == 'f' || ch == 'F' || ch == 'n' || ch == 'N'); !(ch == '0' || ch == 'f' || ch == 'F' || ch == 'n' || ch == 'N');
......
...@@ -119,8 +119,7 @@ LeastSq MinimalLeastSq(const std::vector<int>& n, ...@@ -119,8 +119,7 @@ LeastSq MinimalLeastSq(const std::vector<int>& n,
// this one. If it is oAuto, it will be calculated the best // this one. If it is oAuto, it will be calculated the best
// fitting curve. // fitting curve.
LeastSq MinimalLeastSq(const std::vector<int>& n, LeastSq MinimalLeastSq(const std::vector<int>& n,
const std::vector<double>& time, const std::vector<double>& time, const BigO complexity) {
const BigO complexity) {
CHECK_EQ(n.size(), time.size()); CHECK_EQ(n.size(), time.size());
CHECK_GE(n.size(), 2); // Do not compute fitting curve is less than two CHECK_GE(n.size(), 2); // Do not compute fitting curve is less than two
// benchmark runs are given // benchmark runs are given
......
...@@ -47,10 +47,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO( ...@@ -47,10 +47,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
// parameter will return the best fitting curve detected. // parameter will return the best fitting curve detected.
struct LeastSq { struct LeastSq {
LeastSq() : LeastSq() : coef(0.0), rms(0.0), complexity(oNone) {}
coef(0.0),
rms(0.0),
complexity(oNone) {}
double coef; double coef;
double rms; double rms;
...@@ -60,5 +57,5 @@ struct LeastSq { ...@@ -60,5 +57,5 @@ struct LeastSq {
// Function to return an string for the calculated complexity // Function to return an string for the calculated complexity
std::string GetBigOString(BigO complexity); std::string GetBigOString(BigO complexity);
} // end namespace benchmark } // end namespace benchmark
#endif // COMPLEXITY_H_ #endif // COMPLEXITY_H_
...@@ -39,46 +39,45 @@ bool ConsoleReporter::ReportContext(const Context& context) { ...@@ -39,46 +39,45 @@ bool ConsoleReporter::ReportContext(const Context& context) {
#ifdef BENCHMARK_OS_WINDOWS #ifdef BENCHMARK_OS_WINDOWS
if (color_output_ && &std::cout != &GetOutputStream()) { if (color_output_ && &std::cout != &GetOutputStream()) {
GetErrorStream() << "Color printing is only supported for stdout on windows." GetErrorStream()
" Disabling color printing\n"; << "Color printing is only supported for stdout on windows."
color_output_ = false; " Disabling color printing\n";
color_output_ = false;
} }
#endif #endif
std::string str = FormatString("%-*s %13s %13s %10s\n", std::string str =
static_cast<int>(name_field_width_), "Benchmark", FormatString("%-*s %13s %13s %10s\n", static_cast<int>(name_field_width_),
"Time", "CPU", "Iterations"); "Benchmark", "Time", "CPU", "Iterations");
GetOutputStream() << str << std::string(str.length() - 1, '-') << "\n"; GetOutputStream() << str << std::string(str.length() - 1, '-') << "\n";
return true; return true;
} }
void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) { void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
for (const auto& run : reports) for (const auto& run : reports) PrintRunData(run);
PrintRunData(run);
} }
static void IgnoreColorPrint(std::ostream& out, LogColor, static void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt,
const char* fmt, ...) ...) {
{ va_list args;
va_list args; va_start(args, fmt);
va_start(args, fmt); out << FormatString(fmt, args);
out << FormatString(fmt, args); va_end(args);
va_end(args);
} }
void ConsoleReporter::PrintRunData(const Run& result) { void ConsoleReporter::PrintRunData(const Run& result) {
typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...); typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...);
auto& Out = GetOutputStream(); auto& Out = GetOutputStream();
PrinterFn* printer = color_output_ ? (PrinterFn*)ColorPrintf PrinterFn* printer =
: IgnoreColorPrint; color_output_ ? (PrinterFn*)ColorPrintf : IgnoreColorPrint;
auto name_color = auto name_color =
(result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN; (result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN;
printer(Out, name_color, "%-*s ", name_field_width_, printer(Out, name_color, "%-*s ", name_field_width_,
result.benchmark_name.c_str()); result.benchmark_name.c_str());
if (result.error_occurred) { if (result.error_occurred) {
printer(Out, COLOR_RED, "ERROR OCCURRED: \'%s\'", printer(Out, COLOR_RED, "ERROR OCCURRED: \'%s\'",
result.error_message.c_str()); result.error_message.c_str());
printer(Out, COLOR_DEFAULT, "\n"); printer(Out, COLOR_DEFAULT, "\n");
return; return;
} }
...@@ -91,24 +90,24 @@ void ConsoleReporter::PrintRunData(const Run& result) { ...@@ -91,24 +90,24 @@ void ConsoleReporter::PrintRunData(const Run& result) {
// Format items per second // Format items per second
std::string items; std::string items;
if (result.items_per_second > 0) { if (result.items_per_second > 0) {
items = StrCat(" ", HumanReadableNumber(result.items_per_second), items =
" items/s"); StrCat(" ", HumanReadableNumber(result.items_per_second), " items/s");
} }
const double real_time = result.GetAdjustedRealTime(); const double real_time = result.GetAdjustedRealTime();
const double cpu_time = result.GetAdjustedCPUTime(); const double cpu_time = result.GetAdjustedCPUTime();
if (result.report_big_o) { if (result.report_big_o) {
std::string big_o = GetBigOString(result.complexity); std::string big_o = GetBigOString(result.complexity);
printer(Out, COLOR_YELLOW, "%10.2f %s %10.2f %s ", real_time, printer(Out, COLOR_YELLOW, "%10.2f %s %10.2f %s ", real_time, big_o.c_str(),
big_o.c_str(), cpu_time, big_o.c_str()); cpu_time, big_o.c_str());
} else if (result.report_rms) { } else if (result.report_rms) {
printer(Out, COLOR_YELLOW, "%10.0f %% %10.0f %% ", real_time * 100, printer(Out, COLOR_YELLOW, "%10.0f %% %10.0f %% ", real_time * 100,
cpu_time * 100); cpu_time * 100);
} else { } else {
const char* timeLabel = GetTimeUnitString(result.time_unit); const char* timeLabel = GetTimeUnitString(result.time_unit);
printer(Out, COLOR_YELLOW, "%10.0f %s %10.0f %s ", real_time, timeLabel, printer(Out, COLOR_YELLOW, "%10.0f %s %10.0f %s ", real_time, timeLabel,
cpu_time, timeLabel); cpu_time, timeLabel);
} }
if (!result.report_big_o && !result.report_rms) { if (!result.report_big_o && !result.report_rms) {
......
...@@ -31,38 +31,28 @@ namespace benchmark { ...@@ -31,38 +31,28 @@ namespace benchmark {
namespace { namespace {
std::vector<std::string> elements = { std::vector<std::string> elements = {
"name", "name", "iterations", "real_time", "cpu_time",
"iterations", "time_unit", "bytes_per_second", "items_per_second", "label",
"real_time", "error_occurred", "error_message"};
"cpu_time",
"time_unit",
"bytes_per_second",
"items_per_second",
"label",
"error_occurred",
"error_message"
};
} }
bool CSVReporter::ReportContext(const Context& context) { bool CSVReporter::ReportContext(const Context& context) {
PrintBasicContext(&GetErrorStream(), context); PrintBasicContext(&GetErrorStream(), context);
std::ostream& Out = GetOutputStream(); std::ostream& Out = GetOutputStream();
for (auto B = elements.begin(); B != elements.end(); ) { for (auto B = elements.begin(); B != elements.end();) {
Out << *B++; Out << *B++;
if (B != elements.end()) if (B != elements.end()) Out << ",";
Out << ",";
} }
Out << "\n"; Out << "\n";
return true; return true;
} }
void CSVReporter::ReportRuns(const std::vector<Run> & reports) { void CSVReporter::ReportRuns(const std::vector<Run>& reports) {
for (const auto& run : reports) for (const auto& run : reports) PrintRunData(run);
PrintRunData(run);
} }
void CSVReporter::PrintRunData(const Run & run) { void CSVReporter::PrintRunData(const Run& run) {
std::ostream& Out = GetOutputStream(); std::ostream& Out = GetOutputStream();
// Field with embedded double-quote characters must be doubled and the field // Field with embedded double-quote characters must be doubled and the field
......
...@@ -4,40 +4,39 @@ ...@@ -4,40 +4,39 @@
#include "benchmark/macros.h" #include "benchmark/macros.h"
#ifndef __has_feature #ifndef __has_feature
# define __has_feature(x) 0 #define __has_feature(x) 0
#endif #endif
#if defined(__clang__) #if defined(__clang__)
# define COMPILER_CLANG #define COMPILER_CLANG
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# define COMPILER_MSVC #define COMPILER_MSVC
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define COMPILER_GCC #define COMPILER_GCC
#endif #endif
#if __has_feature(cxx_attributes) #if __has_feature(cxx_attributes)
# define BENCHMARK_NORETURN [[noreturn]] #define BENCHMARK_NORETURN [[noreturn]]
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define BENCHMARK_NORETURN __attribute__((noreturn)) #define BENCHMARK_NORETURN __attribute__((noreturn))
#elif defined(COMPILER_MSVC) #elif defined(COMPILER_MSVC)
# define BENCHMARK_NORETURN __declspec(noreturn) #define BENCHMARK_NORETURN __declspec(noreturn)
#else #else
# define BENCHMARK_NORETURN #define BENCHMARK_NORETURN
#endif #endif
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
# define BENCHMARK_OS_CYGWIN 1 #define BENCHMARK_OS_CYGWIN 1
#elif defined(_WIN32) #elif defined(_WIN32)
# define BENCHMARK_OS_WINDOWS 1 #define BENCHMARK_OS_WINDOWS 1
#elif defined(__APPLE__) #elif defined(__APPLE__)
// TODO(ericwf) This doesn't actually check that it is a Mac OSX system. Just // TODO(ericwf) This doesn't actually check that it is a Mac OSX system. Just
// that it is an apple system. // that it is an apple system.
# define BENCHMARK_OS_MACOSX 1 #define BENCHMARK_OS_MACOSX 1
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
# define BENCHMARK_OS_FREEBSD 1 #define BENCHMARK_OS_FREEBSD 1
#elif defined(__linux__) #elif defined(__linux__)
# define BENCHMARK_OS_LINUX 1 #define BENCHMARK_OS_LINUX 1
#endif #endif
#endif // BENCHMARK_INTERNAL_MACROS_H_
#endif // BENCHMARK_INTERNAL_MACROS_H_
...@@ -47,11 +47,9 @@ std::string FormatKV(std::string const& key, int64_t value) { ...@@ -47,11 +47,9 @@ std::string FormatKV(std::string const& key, int64_t value) {
return ss.str(); return ss.str();
} }
int64_t RoundDouble(double v) { int64_t RoundDouble(double v) { return static_cast<int64_t>(v + 0.5); }
return static_cast<int64_t>(v + 0.5);
}
} // end namespace } // end namespace
bool JSONReporter::ReportContext(const Context& context) { bool JSONReporter::ReportContext(const Context& context) {
std::ostream& out = GetOutputStream(); std::ostream& out = GetOutputStream();
...@@ -66,14 +64,11 @@ bool JSONReporter::ReportContext(const Context& context) { ...@@ -66,14 +64,11 @@ bool JSONReporter::ReportContext(const Context& context) {
std::string walltime_value = LocalDateTimeString(); std::string walltime_value = LocalDateTimeString();
out << indent << FormatKV("date", walltime_value) << ",\n"; out << indent << FormatKV("date", walltime_value) << ",\n";
out << indent out << indent << FormatKV("num_cpus", static_cast<int64_t>(context.num_cpus))
<< FormatKV("num_cpus", static_cast<int64_t>(context.num_cpus))
<< ",\n"; << ",\n";
out << indent out << indent << FormatKV("mhz_per_cpu", RoundDouble(context.mhz_per_cpu))
<< FormatKV("mhz_per_cpu", RoundDouble(context.mhz_per_cpu))
<< ",\n"; << ",\n";
out << indent out << indent << FormatKV("cpu_scaling_enabled", context.cpu_scaling_enabled)
<< FormatKV("cpu_scaling_enabled", context.cpu_scaling_enabled)
<< ",\n"; << ",\n";
#if defined(NDEBUG) #if defined(NDEBUG)
...@@ -118,28 +113,20 @@ void JSONReporter::Finalize() { ...@@ -118,28 +113,20 @@ void JSONReporter::Finalize() {
void JSONReporter::PrintRunData(Run const& run) { void JSONReporter::PrintRunData(Run const& run) {
std::string indent(6, ' '); std::string indent(6, ' ');
std::ostream& out = GetOutputStream(); std::ostream& out = GetOutputStream();
out << indent << FormatKV("name", run.benchmark_name) << ",\n";
if (run.error_occurred) {
out << indent << FormatKV("error_occurred", run.error_occurred) << ",\n";
out << indent << FormatKV("error_message", run.error_message) << ",\n";
}
if (!run.report_big_o && !run.report_rms) {
out << indent << FormatKV("iterations", run.iterations) << ",\n";
out << indent out << indent
<< FormatKV("name", run.benchmark_name) << FormatKV("real_time", RoundDouble(run.GetAdjustedRealTime()))
<< ",\n"; << ",\n";
if (run.error_occurred) { out << indent
out << indent << FormatKV("cpu_time", RoundDouble(run.GetAdjustedCPUTime()));
<< FormatKV("error_occurred", run.error_occurred) out << ",\n"
<< ",\n"; << indent << FormatKV("time_unit", GetTimeUnitString(run.time_unit));
out << indent
<< FormatKV("error_message", run.error_message)
<< ",\n";
}
if (!run.report_big_o && !run.report_rms) {
out << indent
<< FormatKV("iterations", run.iterations)
<< ",\n";
out << indent
<< FormatKV("real_time", RoundDouble(run.GetAdjustedRealTime()))
<< ",\n";
out << indent
<< FormatKV("cpu_time", RoundDouble(run.GetAdjustedCPUTime()));
out << ",\n" << indent
<< FormatKV("time_unit", GetTimeUnitString(run.time_unit));
} else if (run.report_big_o) { } else if (run.report_big_o) {
out << indent out << indent
<< FormatKV("cpu_coefficient", RoundDouble(run.GetAdjustedCPUTime())) << FormatKV("cpu_coefficient", RoundDouble(run.GetAdjustedCPUTime()))
...@@ -147,15 +134,11 @@ void JSONReporter::PrintRunData(Run const& run) { ...@@ -147,15 +134,11 @@ void JSONReporter::PrintRunData(Run const& run) {
out << indent out << indent
<< FormatKV("real_coefficient", RoundDouble(run.GetAdjustedRealTime())) << FormatKV("real_coefficient", RoundDouble(run.GetAdjustedRealTime()))
<< ",\n"; << ",\n";
out << indent << FormatKV("big_o", GetBigOString(run.complexity)) << ",\n";
out << indent << FormatKV("time_unit", GetTimeUnitString(run.time_unit));
} else if (run.report_rms) {
out << indent out << indent
<< FormatKV("big_o", GetBigOString(run.complexity)) << FormatKV("rms", RoundDouble(run.GetAdjustedCPUTime() * 100)) << '%';
<< ",\n";
out << indent
<< FormatKV("time_unit", GetTimeUnitString(run.time_unit));
} else if(run.report_rms) {
out << indent
<< FormatKV("rms", RoundDouble(run.GetAdjustedCPUTime()*100))
<< '%';
} }
if (run.bytes_per_second > 0.0) { if (run.bytes_per_second > 0.0) {
out << ",\n" out << ",\n"
...@@ -168,9 +151,7 @@ void JSONReporter::PrintRunData(Run const& run) { ...@@ -168,9 +151,7 @@ void JSONReporter::PrintRunData(Run const& run) {
<< FormatKV("items_per_second", RoundDouble(run.items_per_second)); << FormatKV("items_per_second", RoundDouble(run.items_per_second));
} }
if (!run.report_label.empty()) { if (!run.report_label.empty()) {
out << ",\n" out << ",\n" << indent << FormatKV("label", run.report_label);
<< indent
<< FormatKV("label", run.report_label);
} }
out << '\n'; out << '\n';
} }
......
...@@ -63,10 +63,11 @@ inline LogType& GetLogInstanceForLevel(int level) { ...@@ -63,10 +63,11 @@ inline LogType& GetLogInstanceForLevel(int level) {
return GetNullLogInstance(); return GetNullLogInstance();
} }
} // end namespace internal } // end namespace internal
} // end namespace benchmark } // end namespace benchmark
#define VLOG(x) (::benchmark::internal::GetLogInstanceForLevel(x) \ #define VLOG(x) \
<< "-- LOG(" << x << "): ") (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \
" ")
#endif #endif
\ No newline at end of file
#ifndef BENCHMARK_MUTEX_H_ #ifndef BENCHMARK_MUTEX_H_
#define BENCHMARK_MUTEX_H_ #define BENCHMARK_MUTEX_H_
#include <mutex>
#include <condition_variable> #include <condition_variable>
#include <mutex>
#include "check.h" #include "check.h"
// Enable thread safety attributes only with clang. // Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers. // The attributes can be safely erased when compiling with other compilers.
#if defined(HAVE_THREAD_SAFETY_ATTRIBUTES) #if defined(HAVE_THREAD_SAFETY_ATTRIBUTES)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else #else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif #endif
#define CAPABILITY(x) \ #define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define SCOPED_CAPABILITY \ #define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define GUARDED_BY(x) \ #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define PT_GUARDED_BY(x) \ #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define ACQUIRED_BEFORE(...) \ #define ACQUIRED_BEFORE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
...@@ -56,22 +52,18 @@ ...@@ -56,22 +52,18 @@
#define TRY_ACQUIRE_SHARED(...) \ #define TRY_ACQUIRE_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
#define EXCLUDES(...) \ #define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define ASSERT_CAPABILITY(x) \ #define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define ASSERT_SHARED_CAPABILITY(x) \ #define ASSERT_SHARED_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
#define RETURN_CAPABILITY(x) \ #define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define NO_THREAD_SAFETY_ANALYSIS \ #define NO_THREAD_SAFETY_ANALYSIS \
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
namespace benchmark { namespace benchmark {
typedef std::condition_variable Condition; typedef std::condition_variable Condition;
...@@ -80,30 +72,27 @@ typedef std::condition_variable Condition; ...@@ -80,30 +72,27 @@ typedef std::condition_variable Condition;
// we can annotate them with thread safety attributes and use the // we can annotate them with thread safety attributes and use the
// -Wthread-safety warning with clang. The standard library types cannot be // -Wthread-safety warning with clang. The standard library types cannot be
// used directly because they do not provided the required annotations. // used directly because they do not provided the required annotations.
class CAPABILITY("mutex") Mutex class CAPABILITY("mutex") Mutex {
{ public:
public:
Mutex() {} Mutex() {}
void lock() ACQUIRE() { mut_.lock(); } void lock() ACQUIRE() { mut_.lock(); }
void unlock() RELEASE() { mut_.unlock(); } void unlock() RELEASE() { mut_.unlock(); }
std::mutex& native_handle() { std::mutex& native_handle() { return mut_; }
return mut_;
} private:
private:
std::mutex mut_; std::mutex mut_;
}; };
class SCOPED_CAPABILITY MutexLock {
class SCOPED_CAPABILITY MutexLock
{
typedef std::unique_lock<std::mutex> MutexLockImp; typedef std::unique_lock<std::mutex> MutexLockImp;
public:
MutexLock(Mutex& m) ACQUIRE(m) : ml_(m.native_handle()) public:
{ } MutexLock(Mutex& m) ACQUIRE(m) : ml_(m.native_handle()) {}
~MutexLock() RELEASE() {} ~MutexLock() RELEASE() {}
MutexLockImp& native_handle() { return ml_; } MutexLockImp& native_handle() { return ml_; }
private:
private:
MutexLockImp ml_; MutexLockImp ml_;
}; };
...@@ -161,6 +150,6 @@ class Barrier { ...@@ -161,6 +150,6 @@ class Barrier {
} }
}; };
} // end namespace benchmark } // end namespace benchmark
#endif // BENCHMARK_MUTEX_H_ #endif // BENCHMARK_MUTEX_H_
...@@ -46,19 +46,19 @@ class Regex { ...@@ -46,19 +46,19 @@ class Regex {
// Returns whether str matches the compiled regular expression. // Returns whether str matches the compiled regular expression.
bool Match(const std::string& str); bool Match(const std::string& str);
private:
private:
bool init_; bool init_;
// Underlying regular expression object // Underlying regular expression object
#if defined(HAVE_STD_REGEX) #if defined(HAVE_STD_REGEX)
std::regex re_; std::regex re_;
#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX) #elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)
regex_t re_; regex_t re_;
#else #else
# error No regular expression backend implementation available #error No regular expression backend implementation available
#endif #endif
}; };
#if defined(HAVE_STD_REGEX) #if defined(HAVE_STD_REGEX)
inline bool Regex::Init(const std::string& spec, std::string* error) { inline bool Regex::Init(const std::string& spec, std::string* error) {
...@@ -74,7 +74,7 @@ inline bool Regex::Init(const std::string& spec, std::string* error) { ...@@ -74,7 +74,7 @@ inline bool Regex::Init(const std::string& spec, std::string* error) {
return init_; return init_;
} }
inline Regex::~Regex() { } inline Regex::~Regex() {}
inline bool Regex::Match(const std::string& str) { inline bool Regex::Match(const std::string& str) {
if (!init_) { if (!init_) {
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <vector>
#include <tuple> #include <tuple>
#include <vector>
#include "check.h" #include "check.h"
#include "stat.h" #include "stat.h"
...@@ -27,49 +27,42 @@ ...@@ -27,49 +27,42 @@
namespace benchmark { namespace benchmark {
BenchmarkReporter::BenchmarkReporter() BenchmarkReporter::BenchmarkReporter()
: output_stream_(&std::cout), error_stream_(&std::cerr) : output_stream_(&std::cout), error_stream_(&std::cerr) {}
{
}
BenchmarkReporter::~BenchmarkReporter() { BenchmarkReporter::~BenchmarkReporter() {}
}
void BenchmarkReporter::PrintBasicContext(std::ostream *out_ptr, void BenchmarkReporter::PrintBasicContext(std::ostream *out_ptr,
Context const &context) { Context const &context) {
CHECK(out_ptr) << "cannot be null"; CHECK(out_ptr) << "cannot be null";
auto& Out = *out_ptr; auto &Out = *out_ptr;
Out << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu Out << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu
<< " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n"; << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n";
Out << LocalDateTimeString() << "\n"; Out << LocalDateTimeString() << "\n";
if (context.cpu_scaling_enabled) { if (context.cpu_scaling_enabled) {
Out << "***WARNING*** CPU scaling is enabled, the benchmark " Out << "***WARNING*** CPU scaling is enabled, the benchmark "
"real time measurements may be noisy and will incur extra " "real time measurements may be noisy and will incur extra "
"overhead.\n"; "overhead.\n";
} }
#ifndef NDEBUG #ifndef NDEBUG
Out << "***WARNING*** Library was built as DEBUG. Timings may be " Out << "***WARNING*** Library was built as DEBUG. Timings may be "
"affected.\n"; "affected.\n";
#endif #endif
} }
double BenchmarkReporter::Run::GetAdjustedRealTime() const { double BenchmarkReporter::Run::GetAdjustedRealTime() const {
double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit); double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit);
if (iterations != 0) if (iterations != 0) new_time /= static_cast<double>(iterations);
new_time /= static_cast<double>(iterations);
return new_time; return new_time;
} }
double BenchmarkReporter::Run::GetAdjustedCPUTime() const { double BenchmarkReporter::Run::GetAdjustedCPUTime() const {
double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit); double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit);
if (iterations != 0) if (iterations != 0) new_time /= static_cast<double>(iterations);
new_time /= static_cast<double>(iterations);
return new_time; return new_time;
} }
} // end namespace benchmark
} // end namespace benchmark
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include <ostream> #include <ostream>
#include <type_traits> #include <type_traits>
namespace benchmark { namespace benchmark {
template <typename VType, typename NumType> template <typename VType, typename NumType>
...@@ -136,7 +135,7 @@ class Stat1 { ...@@ -136,7 +135,7 @@ class Stat1 {
private: private:
static_assert(std::is_integral<NumType>::value && static_assert(std::is_integral<NumType>::value &&
!std::is_same<NumType, bool>::value, !std::is_same<NumType, bool>::value,
"NumType must be an integral type that is not bool."); "NumType must be an integral type that is not bool.");
// Let i be the index of the samples provided (using +=) // Let i be the index of the samples provided (using +=)
// and weight[i],value[i] be the data of sample #i // and weight[i],value[i] be the data of sample #i
......
#include "string_util.h" #include "string_util.h"
#include <array>
#include <cmath> #include <cmath>
#include <cstdarg> #include <cstdarg>
#include <array> #include <cstdio>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <stdio.h>
#include "arraysize.h" #include "arraysize.h"
...@@ -27,7 +27,7 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits), ...@@ -27,7 +27,7 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
static const int64_t kUnitsSize = arraysize(kBigSIUnits); static const int64_t kUnitsSize = arraysize(kBigSIUnits);
} // end anonymous namespace } // end anonymous namespace
void ToExponentAndMantissa(double val, double thresh, int precision, void ToExponentAndMantissa(double val, double thresh, int precision,
double one_k, std::string* mantissa, double one_k, std::string* mantissa,
...@@ -118,8 +118,7 @@ std::string HumanReadableNumber(double n) { ...@@ -118,8 +118,7 @@ std::string HumanReadableNumber(double n) {
return ToBinaryStringFullySpecified(n, 1.1, 1); return ToBinaryStringFullySpecified(n, 1.1, 1);
} }
std::string StringPrintFImp(const char *msg, va_list args) std::string StringPrintFImp(const char* msg, va_list args) {
{
// we might need a second shot at this, so pre-emptivly make a copy // we might need a second shot at this, so pre-emptivly make a copy
va_list args_cp; va_list args_cp;
va_copy(args_cp, args); va_copy(args_cp, args);
...@@ -128,14 +127,14 @@ std::string StringPrintFImp(const char *msg, va_list args) ...@@ -128,14 +127,14 @@ std::string StringPrintFImp(const char *msg, va_list args)
// allocation guess what the size might be // allocation guess what the size might be
std::array<char, 256> local_buff; std::array<char, 256> local_buff;
std::size_t size = local_buff.size(); std::size_t size = local_buff.size();
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation in the android-ndk // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
// in the android-ndk
auto ret = vsnprintf(local_buff.data(), size, msg, args_cp); auto ret = vsnprintf(local_buff.data(), size, msg, args_cp);
va_end(args_cp); va_end(args_cp);
// handle empty expansion // handle empty expansion
if (ret == 0) if (ret == 0) return std::string{};
return std::string{};
if (static_cast<std::size_t>(ret) < size) if (static_cast<std::size_t>(ret) < size)
return std::string(local_buff.data()); return std::string(local_buff.data());
...@@ -143,13 +142,13 @@ std::string StringPrintFImp(const char *msg, va_list args) ...@@ -143,13 +142,13 @@ std::string StringPrintFImp(const char *msg, va_list args)
// add 1 to size to account for null-byte in size cast to prevent overflow // add 1 to size to account for null-byte in size cast to prevent overflow
size = static_cast<std::size_t>(ret) + 1; size = static_cast<std::size_t>(ret) + 1;
auto buff_ptr = std::unique_ptr<char[]>(new char[size]); auto buff_ptr = std::unique_ptr<char[]>(new char[size]);
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation in the android-ndk // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
// in the android-ndk
ret = vsnprintf(buff_ptr.get(), size, msg, args); ret = vsnprintf(buff_ptr.get(), size, msg, args);
return std::string(buff_ptr.get()); return std::string(buff_ptr.get());
} }
std::string StringPrintF(const char* format, ...) std::string StringPrintF(const char* format, ...) {
{
va_list args; va_list args;
va_start(args, format); va_start(args, format);
std::string tmp = StringPrintFImp(format, args); std::string tmp = StringPrintFImp(format, args);
...@@ -160,10 +159,10 @@ std::string StringPrintF(const char* format, ...) ...@@ -160,10 +159,10 @@ std::string StringPrintF(const char* format, ...)
void ReplaceAll(std::string* str, const std::string& from, void ReplaceAll(std::string* str, const std::string& from,
const std::string& to) { const std::string& to) {
std::size_t start = 0; std::size_t start = 0;
while((start = str->find(from, start)) != std::string::npos) { while ((start = str->find(from, start)) != std::string::npos) {
str->replace(start, from.length(), to); str->replace(start, from.length(), to);
start += to.length(); start += to.length();
} }
} }
} // end namespace benchmark } // end namespace benchmark
#ifndef BENCHMARK_STRING_UTIL_H_ #ifndef BENCHMARK_STRING_UTIL_H_
#define BENCHMARK_STRING_UTIL_H_ #define BENCHMARK_STRING_UTIL_H_
#include <string>
#include <sstream> #include <sstream>
#include <string>
#include <utility> #include <utility>
#include "internal_macros.h" #include "internal_macros.h"
...@@ -14,23 +14,19 @@ std::string HumanReadableNumber(double n); ...@@ -14,23 +14,19 @@ std::string HumanReadableNumber(double n);
std::string StringPrintF(const char* format, ...); std::string StringPrintF(const char* format, ...);
inline std::ostream& inline std::ostream& StringCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {
StringCatImp(std::ostream& out) BENCHMARK_NOEXCEPT
{
return out; return out;
} }
template <class First, class ...Rest> template <class First, class... Rest>
inline std::ostream& inline std::ostream& StringCatImp(std::ostream& out, First&& f,
StringCatImp(std::ostream& out, First&& f, Rest&&... rest) Rest&&... rest) {
{
out << std::forward<First>(f); out << std::forward<First>(f);
return StringCatImp(out, std::forward<Rest>(rest)...); return StringCatImp(out, std::forward<Rest>(rest)...);
} }
template<class ...Args> template <class... Args>
inline std::string StrCat(Args&&... args) inline std::string StrCat(Args&&... args) {
{
std::ostringstream ss; std::ostringstream ss;
StringCatImp(ss, std::forward<Args>(args)...); StringCatImp(ss, std::forward<Args>(args)...);
return ss.str(); return ss.str();
...@@ -39,6 +35,6 @@ inline std::string StrCat(Args&&... args) ...@@ -39,6 +35,6 @@ inline std::string StrCat(Args&&... args)
void ReplaceAll(std::string* str, const std::string& from, void ReplaceAll(std::string* str, const std::string& from,
const std::string& to); const std::string& to);
} // end namespace benchmark } // end namespace benchmark
#endif // BENCHMARK_STRING_UTIL_H_ #endif // BENCHMARK_STRING_UTIL_H_
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
#ifdef BENCHMARK_OS_WINDOWS #ifdef BENCHMARK_OS_WINDOWS
#include <Shlwapi.h> #include <Shlwapi.h>
#include <Windows.h>
#include <VersionHelpers.h> #include <VersionHelpers.h>
#include <Windows.h>
#else #else
#include <fcntl.h> #include <fcntl.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
#include <unistd.h> #include <unistd.h>
#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX #if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX
#include <sys/sysctl.h> #include <sys/sysctl.h>
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#endif #endif
#include <cerrno> #include <cerrno>
#include <cstdio>
#include <cstdint> #include <cstdint>
#include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
...@@ -126,7 +126,8 @@ void InitializeSystemInfo() { ...@@ -126,7 +126,8 @@ void InitializeSystemInfo() {
if (fd == -1) { if (fd == -1) {
perror(pname); perror(pname);
if (!saw_mhz) { if (!saw_mhz) {
cpuinfo_cycles_per_second = static_cast<double>(EstimateCyclesPerSecond()); cpuinfo_cycles_per_second =
static_cast<double>(EstimateCyclesPerSecond());
} }
return; return;
} }
...@@ -196,7 +197,8 @@ void InitializeSystemInfo() { ...@@ -196,7 +197,8 @@ void InitializeSystemInfo() {
cpuinfo_cycles_per_second = bogo_clock; cpuinfo_cycles_per_second = bogo_clock;
} else { } else {
// If we don't even have bogomips, we'll use the slow estimation. // If we don't even have bogomips, we'll use the slow estimation.
cpuinfo_cycles_per_second = static_cast<double>(EstimateCyclesPerSecond()); cpuinfo_cycles_per_second =
static_cast<double>(EstimateCyclesPerSecond());
} }
} }
if (num_cpus == 0) { if (num_cpus == 0) {
...@@ -238,7 +240,6 @@ void InitializeSystemInfo() { ...@@ -238,7 +240,6 @@ void InitializeSystemInfo() {
} }
// TODO: also figure out cpuinfo_num_cpus // TODO: also figure out cpuinfo_num_cpus
#elif defined BENCHMARK_OS_WINDOWS #elif defined BENCHMARK_OS_WINDOWS
// In NT, read MHz from the registry. If we fail to do so or we're in win9x // In NT, read MHz from the registry. If we fail to do so or we're in win9x
// then make a crude estimate. // then make a crude estimate.
...@@ -248,15 +249,19 @@ void InitializeSystemInfo() { ...@@ -248,15 +249,19 @@ void InitializeSystemInfo() {
SHGetValueA(HKEY_LOCAL_MACHINE, SHGetValueA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
"~MHz", nullptr, &data, &data_size))) "~MHz", nullptr, &data, &data_size)))
cpuinfo_cycles_per_second = static_cast<double>((int64_t)data * (int64_t)(1000 * 1000)); // was mhz cpuinfo_cycles_per_second =
static_cast<double>((int64_t)data * (int64_t)(1000 * 1000)); // was mhz
else else
cpuinfo_cycles_per_second = static_cast<double>(EstimateCyclesPerSecond()); cpuinfo_cycles_per_second = static_cast<double>(EstimateCyclesPerSecond());
SYSTEM_INFO sysinfo; SYSTEM_INFO sysinfo;
// Use memset as opposed to = {} to avoid GCC missing initializer false positives. // Use memset as opposed to = {} to avoid GCC missing initializer false
// positives.
std::memset(&sysinfo, 0, sizeof(SYSTEM_INFO)); std::memset(&sysinfo, 0, sizeof(SYSTEM_INFO));
GetSystemInfo(&sysinfo); GetSystemInfo(&sysinfo);
cpuinfo_num_cpus = sysinfo.dwNumberOfProcessors; // number of logical processors in the current group cpuinfo_num_cpus = sysinfo.dwNumberOfProcessors; // number of logical
// processors in the current
// group
#elif defined BENCHMARK_OS_MACOSX #elif defined BENCHMARK_OS_MACOSX
// returning "mach time units" per second. the current number of elapsed // returning "mach time units" per second. the current number of elapsed
...@@ -277,8 +282,8 @@ void InitializeSystemInfo() { ...@@ -277,8 +282,8 @@ void InitializeSystemInfo() {
int num_cpus = 0; int num_cpus = 0;
size_t size = sizeof(num_cpus); size_t size = sizeof(num_cpus);
int numcpus_name[] = {CTL_HW, HW_NCPU}; int numcpus_name[] = {CTL_HW, HW_NCPU};
if (::sysctl(numcpus_name, arraysize(numcpus_name), &num_cpus, &size, nullptr, 0) == if (::sysctl(numcpus_name, arraysize(numcpus_name), &num_cpus, &size, nullptr,
0 && 0) == 0 &&
(size == sizeof(num_cpus))) (size == sizeof(num_cpus)))
cpuinfo_num_cpus = num_cpus; cpuinfo_num_cpus = num_cpus;
...@@ -316,8 +321,8 @@ bool CpuScalingEnabled() { ...@@ -316,8 +321,8 @@ bool CpuScalingEnabled() {
// local file system. If reading the exported files fails, then we may not be // local file system. If reading the exported files fails, then we may not be
// running on Linux, so we silently ignore all the read errors. // running on Linux, so we silently ignore all the read errors.
for (int cpu = 0, num_cpus = NumCPUs(); cpu < num_cpus; ++cpu) { for (int cpu = 0, num_cpus = NumCPUs(); cpu < num_cpus; ++cpu) {
std::string governor_file = StrCat("/sys/devices/system/cpu/cpu", cpu, std::string governor_file =
"/cpufreq/scaling_governor"); StrCat("/sys/devices/system/cpu/cpu", cpu, "/cpufreq/scaling_governor");
FILE* file = fopen(governor_file.c_str(), "r"); FILE* file = fopen(governor_file.c_str(), "r");
if (!file) break; if (!file) break;
char buff[16]; char buff[16];
......
...@@ -92,16 +92,16 @@ double MakeTime(struct timespec const& ts) { ...@@ -92,16 +92,16 @@ double MakeTime(struct timespec const& ts) {
} }
#endif #endif
BENCHMARK_NORETURN static void DiagnoseAndExit(const char* msg) { BENCHMARK_NORETURN static void DiagnoseAndExit(const char* msg) {
std::cerr << "ERROR: " << msg << std::endl; std::cerr << "ERROR: " << msg << std::endl;
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
} // end namespace } // end namespace
double ProcessCPUUsage() { double ProcessCPUUsage() {
// FIXME We want to use clock_gettime, but its not available in MacOS 10.11. See https://github.com/google/benchmark/pull/292 // FIXME We want to use clock_gettime, but its not available in MacOS 10.11. See
// https://github.com/google/benchmark/pull/292
#if defined(CLOCK_PROCESS_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX) #if defined(CLOCK_PROCESS_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX)
struct timespec spec; struct timespec spec;
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0) if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0)
...@@ -113,23 +113,23 @@ double ProcessCPUUsage() { ...@@ -113,23 +113,23 @@ double ProcessCPUUsage() {
FILETIME exit_time; FILETIME exit_time;
FILETIME kernel_time; FILETIME kernel_time;
FILETIME user_time; FILETIME user_time;
if (GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time, &user_time)) if (GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time,
&user_time))
return MakeTime(kernel_time, user_time); return MakeTime(kernel_time, user_time);
DiagnoseAndExit("GetProccessTimes() failed"); DiagnoseAndExit("GetProccessTimes() failed");
#else #else
struct rusage ru; struct rusage ru;
if (getrusage(RUSAGE_SELF, &ru) == 0) if (getrusage(RUSAGE_SELF, &ru) == 0) return MakeTime(ru);
return MakeTime(ru);
DiagnoseAndExit("clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed"); DiagnoseAndExit("clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed");
#endif #endif
} }
double ThreadCPUUsage() { double ThreadCPUUsage() {
// FIXME We want to use clock_gettime, but its not available in MacOS 10.11. See https://github.com/google/benchmark/pull/292 // FIXME We want to use clock_gettime, but its not available in MacOS 10.11. See
// https://github.com/google/benchmark/pull/292
#if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX) #if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX)
struct timespec ts; struct timespec ts;
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts);
return MakeTime(ts);
DiagnoseAndExit("clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed"); DiagnoseAndExit("clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed");
#elif defined(BENCHMARK_OS_WINDOWS) #elif defined(BENCHMARK_OS_WINDOWS)
HANDLE this_thread = GetCurrentThread(); HANDLE this_thread = GetCurrentThread();
...@@ -144,8 +144,8 @@ double ThreadCPUUsage() { ...@@ -144,8 +144,8 @@ double ThreadCPUUsage() {
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info; thread_basic_info_data_t info;
mach_port_t thread = pthread_mach_thread_np(pthread_self()); mach_port_t thread = pthread_mach_thread_np(pthread_self());
if (thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count) if (thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &count) ==
== KERN_SUCCESS) { KERN_SUCCESS) {
return MakeTime(info); return MakeTime(info);
} }
DiagnoseAndExit("ThreadCPUUsage() failed when evaluating thread_info"); DiagnoseAndExit("ThreadCPUUsage() failed when evaluating thread_info");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment