Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
benchmark
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
benchmark
Commits
332f677b
Commit
332f677b
authored
Oct 07, 2016
by
Dominic Hamon
Committed by
GitHub
Oct 07, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply clang-format to all headers and source (#303)
parent
1100e919
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
335 additions
and
396 deletions
+335
-396
benchmark.h
include/benchmark/benchmark.h
+2
-2
benchmark_api.h
include/benchmark/benchmark_api.h
+0
-0
macros.h
include/benchmark/macros.h
+28
-28
reporter.h
include/benchmark/reporter.h
+20
-27
arraysize.h
src/arraysize.h
+3
-4
benchmark.cc
src/benchmark.cc
+0
-0
benchmark_api_internal.h
src/benchmark_api_internal.h
+23
-22
benchmark_register.cc
src/benchmark_register.cc
+50
-54
check.h
src/check.h
+21
-20
colorprint.cc
src/colorprint.cc
+10
-10
colorprint.h
src/colorprint.h
+3
-2
commandlineflags.cc
src/commandlineflags.cc
+4
-4
complexity.cc
src/complexity.cc
+1
-2
complexity.h
src/complexity.h
+3
-6
console_reporter.cc
src/console_reporter.cc
+25
-26
csv_reporter.cc
src/csv_reporter.cc
+8
-18
internal_macros.h
src/internal_macros.h
+14
-15
json_reporter.cc
src/json_reporter.cc
+22
-41
log.h
src/log.h
+6
-4
mutex.h
src/mutex.h
+23
-34
re.h
src/re.h
+5
-5
reporter.cc
src/reporter.cc
+11
-18
stat.h
src/stat.h
+1
-2
string_util.cc
src/string_util.cc
+12
-13
string_util.h
src/string_util.h
+9
-13
sysinfo.cc
src/sysinfo.cc
+18
-13
timers.cc
src/timers.cc
+13
-13
No files found.
include/benchmark/benchmark.h
View file @
332f677b
...
...
@@ -14,8 +14,8 @@
#ifndef BENCHMARK_BENCHMARK_H_
#define BENCHMARK_BENCHMARK_H_
#include "macros.h"
#include "benchmark_api.h"
#include "macros.h"
#include "reporter.h"
#endif // BENCHMARK_BENCHMARK_H_
#endif
// BENCHMARK_BENCHMARK_H_
include/benchmark/benchmark_api.h
View file @
332f677b
This diff is collapsed.
Click to expand it.
include/benchmark/macros.h
View file @
332f677b
...
...
@@ -19,44 +19,44 @@
#endif
#ifndef BENCHMARK_HAS_CXX11
#
define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName)
\
TypeName(const TypeName&); \
TypeName& operator=(const TypeName&)
#
define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName)
\
TypeName(const TypeName&); \
TypeName& operator=(const TypeName&)
#else
#
define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName)
\
TypeName(const TypeName&) = delete; \
TypeName& operator=(const TypeName&) = delete
#
define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName)
\
TypeName(const TypeName&) = delete; \
TypeName& operator=(const TypeName&) = delete
#endif
#if defined(__GNUC__)
#
define BENCHMARK_UNUSED __attribute__((unused))
#
define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
#
define BENCHMARK_NOEXCEPT noexcept
#
define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
#define BENCHMARK_UNUSED __attribute__((unused))
#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
#define BENCHMARK_NOEXCEPT noexcept
#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
#elif defined(_MSC_VER) && !defined(__clang__)
# define BENCHMARK_UNUSED
# define BENCHMARK_ALWAYS_INLINE __forceinline
# if _MSC_VER >= 1900
# define BENCHMARK_NOEXCEPT noexcept
# define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
# else
# define BENCHMARK_NOEXCEPT
# define BENCHMARK_NOEXCEPT_OP(x)
# endif
# define __func__ __FUNCTION__
#define BENCHMARK_UNUSED
#define BENCHMARK_ALWAYS_INLINE __forceinline
#if _MSC_VER >= 1900
#define BENCHMARK_NOEXCEPT noexcept
#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
#else
# define BENCHMARK_UNUSED
# define BENCHMARK_ALWAYS_INLINE
# define BENCHMARK_NOEXCEPT
# define BENCHMARK_NOEXCEPT_OP(x)
#define BENCHMARK_NOEXCEPT
#define BENCHMARK_NOEXCEPT_OP(x)
#endif
#define __func__ __FUNCTION__
#else
#define BENCHMARK_UNUSED
#define BENCHMARK_ALWAYS_INLINE
#define BENCHMARK_NOEXCEPT
#define BENCHMARK_NOEXCEPT_OP(x)
#endif
#if defined(__GNUC__)
#
define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
#
define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
#else
#
define BENCHMARK_BUILTIN_EXPECT(x, y) x
#
define BENCHMARK_DEPRECATED_MSG(msg)
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
#define BENCHMARK_DEPRECATED_MSG(msg)
#endif
#if defined(__GNUC__) && !defined(__clang__)
...
...
include/benchmark/reporter.h
View file @
332f677b
...
...
@@ -41,20 +41,20 @@ class BenchmarkReporter {
};
struct
Run
{
Run
()
:
error_occurred
(
false
),
iterations
(
1
),
time_unit
(
kNanosecond
),
real_accumulated_time
(
0
),
cpu_accumulated_time
(
0
),
bytes_per_second
(
0
),
items_per_second
(
0
),
max_heapbytes_used
(
0
),
complexity
(
oNone
),
complexity_lambda
(),
complexity_n
(
0
),
report_big_o
(
false
),
report_rms
(
false
)
{}
Run
()
:
error_occurred
(
false
),
iterations
(
1
),
time_unit
(
kNanosecond
),
real_accumulated_time
(
0
),
cpu_accumulated_time
(
0
),
bytes_per_second
(
0
),
items_per_second
(
0
),
max_heapbytes_used
(
0
),
complexity
(
oNone
),
complexity_lambda
(),
complexity_n
(
0
),
report_big_o
(
false
),
report_rms
(
false
)
{}
std
::
string
benchmark_name
;
std
::
string
report_label
;
// Empty if not set by benchmark.
...
...
@@ -134,13 +134,9 @@ class BenchmarkReporter {
error_stream_
=
err
;
}
std
::
ostream
&
GetOutputStream
()
const
{
return
*
output_stream_
;
}
std
::
ostream
&
GetOutputStream
()
const
{
return
*
output_stream_
;
}
std
::
ostream
&
GetErrorStream
()
const
{
return
*
error_stream_
;
}
std
::
ostream
&
GetErrorStream
()
const
{
return
*
error_stream_
;
}
virtual
~
BenchmarkReporter
();
...
...
@@ -157,22 +153,19 @@ class BenchmarkReporter {
// Simple reporter that outputs benchmark data to the console. This is the
// default reporter used by RunSpecifiedBenchmarks().
class
ConsoleReporter
:
public
BenchmarkReporter
{
public
:
enum
OutputOptions
{
OO_None
,
OO_Color
};
public
:
enum
OutputOptions
{
OO_None
,
OO_Color
};
explicit
ConsoleReporter
(
OutputOptions
color_output
=
OO_Color
)
:
name_field_width_
(
0
),
color_output_
(
color_output
==
OO_Color
)
{}
virtual
bool
ReportContext
(
const
Context
&
context
);
virtual
void
ReportRuns
(
const
std
::
vector
<
Run
>&
reports
);
protected
:
protected
:
virtual
void
PrintRunData
(
const
Run
&
report
);
size_t
name_field_width_
;
private
:
private
:
bool
color_output_
;
};
...
...
src/arraysize.h
View file @
332f677b
...
...
@@ -11,7 +11,6 @@ namespace internal {
// a pointer by mistake, you will get a compile-time error.
//
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
...
...
@@ -28,7 +27,7 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
#define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array)))
}
// end namespace internal
}
// end namespace benchmark
}
// end namespace internal
}
// end namespace benchmark
#endif // BENCHMARK_ARRAYSIZE_H_
#endif
// BENCHMARK_ARRAYSIZE_H_
src/benchmark.cc
View file @
332f677b
This diff is collapsed.
Click to expand it.
src/benchmark_api_internal.h
View file @
332f677b
...
...
@@ -3,44 +3,45 @@
#include "benchmark/benchmark_api.h"
#include <string>
#include <vector>
#include <limits>
#include <cmath>
#include <iosfwd>
#include <limits>
#include <string>
#include <vector>
namespace
benchmark
{
namespace
internal
{
// Information kept per benchmark we may want to run
struct
Benchmark
::
Instance
{
std
::
string
name
;
Benchmark
*
benchmark
;
ReportMode
report_mode
;
std
::
string
name
;
Benchmark
*
benchmark
;
ReportMode
report_mode
;
std
::
vector
<
int
>
arg
;
TimeUnit
time_unit
;
int
range_multiplier
;
bool
use_real_time
;
bool
use_manual_time
;
BigO
complexity
;
BigOFunc
*
complexity_lambda
;
bool
last_benchmark_instance
;
int
repetitions
;
double
min_time
;
int
threads
;
// Number of concurrent threads to us
TimeUnit
time_unit
;
int
range_multiplier
;
bool
use_real_time
;
bool
use_manual_time
;
BigO
complexity
;
BigOFunc
*
complexity_lambda
;
bool
last_benchmark_instance
;
int
repetitions
;
double
min_time
;
int
threads
;
// Number of concurrent threads to us
};
bool
FindBenchmarksInternal
(
const
std
::
string
&
re
,
std
::
vector
<
Benchmark
::
Instance
>*
benchmarks
,
std
::
ostream
*
Err
);
std
::
vector
<
Benchmark
::
Instance
>*
benchmarks
,
std
::
ostream
*
Err
);
namespace
{
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 internal
}
// end namespace benchmark
}
// end namespace
}
// end namespace internal
}
// end namespace benchmark
#endif // BENCHMARK_API_INTERNAL_H
#endif
// BENCHMARK_API_INTERNAL_H
src/benchmark_register.cc
View file @
332f677b
...
...
@@ -13,23 +13,23 @@
// limitations under the License.
#include "benchmark/benchmark.h"
#include "internal_macros.h"
#include "benchmark_api_internal.h"
#include "internal_macros.h"
#ifndef BENCHMARK_OS_WINDOWS
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
#endif
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <atomic>
#include <condition_variable>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <memory>
#include <thread>
...
...
@@ -74,6 +74,7 @@ class BenchmarkFamilies {
bool
FindBenchmarks
(
const
std
::
string
&
re
,
std
::
vector
<
Benchmark
::
Instance
>*
benchmarks
,
std
::
ostream
*
Err
);
private
:
BenchmarkFamilies
()
{}
...
...
@@ -94,8 +95,7 @@ size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
}
bool
BenchmarkFamilies
::
FindBenchmarks
(
const
std
::
string
&
spec
,
std
::
vector
<
Benchmark
::
Instance
>*
benchmarks
,
const
std
::
string
&
spec
,
std
::
vector
<
Benchmark
::
Instance
>*
benchmarks
,
std
::
ostream
*
ErrStream
)
{
CHECK
(
ErrStream
);
auto
&
Err
=
*
ErrStream
;
...
...
@@ -120,23 +120,21 @@ bool BenchmarkFamilies::FindBenchmarks(
}
const
std
::
vector
<
int
>*
thread_counts
=
(
family
->
thread_counts_
.
empty
()
?
&
one_thread
:
&
static_cast
<
const
std
::
vector
<
int
>&>
(
family
->
thread_counts_
));
?
&
one_thread
:
&
static_cast
<
const
std
::
vector
<
int
>&>
(
family
->
thread_counts_
));
const
size_t
family_size
=
family
->
args_
.
size
()
*
thread_counts
->
size
();
// The benchmark will be run at least 'family_size' different inputs.
// If 'family_size' is very large warn the user.
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
"
;
}
// reserve in the special case the regex ".", since we know the final
// family size.
if
(
spec
==
"."
)
benchmarks
->
reserve
(
family_size
);
if
(
spec
==
"."
)
benchmarks
->
reserve
(
family_size
);
for
(
auto
const
&
args
:
family
->
args_
)
{
for
(
int
num_threads
:
*
thread_counts
)
{
Benchmark
::
Instance
instance
;
instance
.
name
=
family
->
name_
;
instance
.
benchmark
=
family
.
get
();
...
...
@@ -158,15 +156,15 @@ bool BenchmarkFamilies::FindBenchmarks(
}
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
)
{
instance
.
name
+=
StringPrintF
(
"/repeats:%d"
,
family
->
repetitions_
);
instance
.
name
+=
StringPrintF
(
"/repeats:%d"
,
family
->
repetitions_
);
}
if
(
family
->
use_manual_time_
)
{
instance
.
name
+=
"/manual_time"
;
instance
.
name
+=
"/manual_time"
;
}
else
if
(
family
->
use_real_time_
)
{
instance
.
name
+=
"/real_time"
;
instance
.
name
+=
"/real_time"
;
}
// Add the number of threads used to the name
...
...
@@ -185,37 +183,37 @@ bool BenchmarkFamilies::FindBenchmarks(
}
Benchmark
*
RegisterBenchmarkInternal
(
Benchmark
*
bench
)
{
std
::
unique_ptr
<
Benchmark
>
bench_ptr
(
bench
);
BenchmarkFamilies
*
families
=
BenchmarkFamilies
::
GetInstance
();
families
->
AddBenchmark
(
std
::
move
(
bench_ptr
));
return
bench
;
std
::
unique_ptr
<
Benchmark
>
bench_ptr
(
bench
);
BenchmarkFamilies
*
families
=
BenchmarkFamilies
::
GetInstance
();
families
->
AddBenchmark
(
std
::
move
(
bench_ptr
));
return
bench
;
}
// FIXME: This function is a hack so that benchmark.cc can access
// `BenchmarkFamilies`
bool
FindBenchmarksInternal
(
const
std
::
string
&
re
,
std
::
vector
<
Benchmark
::
Instance
>*
benchmarks
,
std
::
ostream
*
Err
)
{
std
::
ostream
*
Err
)
{
return
BenchmarkFamilies
::
GetInstance
()
->
FindBenchmarks
(
re
,
benchmarks
,
Err
);
}
//=============================================================================//
// Benchmark
//=============================================================================//
Benchmark
::
Benchmark
(
const
char
*
name
)
:
name_
(
name
),
report_mode_
(
RM_Unspecified
),
time_unit_
(
kNanosecond
),
range_multiplier_
(
kRangeMultiplier
),
min_time_
(
0
),
repetitions_
(
0
),
use_real_time_
(
false
),
use_manual_time_
(
false
),
complexity_
(
oNone
),
complexity_lambda_
(
nullptr
)
{
}
Benchmark
::~
Benchmark
()
{
}
:
name_
(
name
),
report_mode_
(
RM_Unspecified
),
time_unit_
(
kNanosecond
),
range_multiplier_
(
kRangeMultiplier
),
min_time_
(
0
),
repetitions_
(
0
),
use_real_time_
(
false
),
use_manual_time_
(
false
),
complexity_
(
oNone
),
complexity_lambda_
(
nullptr
)
{}
Benchmark
::~
Benchmark
()
{}
void
Benchmark
::
AddRange
(
std
::
vector
<
int
>*
dst
,
int
lo
,
int
hi
,
int
mult
)
{
CHECK_GE
(
lo
,
0
);
...
...
@@ -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
();
// 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
>
lo
)
{
dst
->
push_back
(
i
);
...
...
@@ -262,13 +260,13 @@ Benchmark* Benchmark::Range(int start, int limit) {
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
()));
std
::
vector
<
std
::
vector
<
int
>>
arglists
(
ranges
.
size
());
std
::
size_t
total
=
1
;
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
();
}
...
...
@@ -299,7 +297,7 @@ Benchmark* Benchmark::DenseRange(int start, int limit, int step) {
CHECK
(
ArgsCnt
()
==
-
1
||
ArgsCnt
()
==
1
);
CHECK_GE
(
start
,
0
);
CHECK_LE
(
start
,
limit
);
for
(
int
arg
=
start
;
arg
<=
limit
;
arg
+=
step
)
{
for
(
int
arg
=
start
;
arg
<=
limit
;
arg
+=
step
)
{
args_
.
push_back
({
arg
});
}
return
this
;
...
...
@@ -340,13 +338,15 @@ Benchmark* Benchmark::MinTime(double t) {
}
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
;
return
this
;
}
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
;
return
this
;
}
...
...
@@ -376,7 +376,7 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
return
this
;
}
Benchmark
*
Benchmark
::
DenseThreadRange
(
int
min_threads
,
int
max_threads
,
Benchmark
*
Benchmark
::
DenseThreadRange
(
int
min_threads
,
int
max_threads
,
int
stride
)
{
CHECK_GT
(
min_threads
,
0
);
CHECK_GE
(
max_threads
,
min_threads
);
...
...
@@ -395,21 +395,17 @@ Benchmark* Benchmark::ThreadPerCpu() {
return
this
;
}
void
Benchmark
::
SetName
(
const
char
*
name
)
{
name_
=
name
;
}
int
Benchmark
::
ArgsCnt
()
const
{
return
args_
.
empty
()
?
-
1
:
static_cast
<
int
>
(
args_
.
front
().
size
());
}
void
Benchmark
::
SetName
(
const
char
*
name
)
{
name_
=
name
;
}
int
Benchmark
::
ArgsCnt
()
const
{
return
args_
.
empty
()
?
-
1
:
static_cast
<
int
>
(
args_
.
front
().
size
());
}
//=============================================================================//
// FunctionBenchmark
//=============================================================================//
void
FunctionBenchmark
::
Run
(
State
&
st
)
{
func_
(
st
);
}
void
FunctionBenchmark
::
Run
(
State
&
st
)
{
func_
(
st
);
}
}
// end namespace internal
}
// end namespace benchmark
}
// end namespace internal
}
// end namespace benchmark
src/check.h
View file @
332f677b
...
...
@@ -13,51 +13,52 @@ namespace internal {
typedef
void
(
AbortHandlerT
)();
inline
AbortHandlerT
*&
GetAbortHandler
()
{
static
AbortHandlerT
*
handler
=
&
std
::
abort
;
return
handler
;
static
AbortHandlerT
*
handler
=
&
std
::
abort
;
return
handler
;
}
BENCHMARK_NORETURN
inline
void
CallAbortHandler
()
{
GetAbortHandler
()();
std
::
abort
();
// fallback to enforce noreturn
GetAbortHandler
()();
std
::
abort
();
// fallback to enforce noreturn
}
// 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
:
public
:
CheckHandler
(
const
char
*
check
,
const
char
*
file
,
const
char
*
func
,
int
line
)
:
log_
(
GetErrorLogInstance
())
{
log_
<<
file
<<
":"
<<
line
<<
": "
<<
func
<<
": Check `"
<<
check
<<
"' failed. "
;
:
log_
(
GetErrorLogInstance
())
{
log_
<<
file
<<
":"
<<
line
<<
": "
<<
func
<<
": Check `"
<<
check
<<
"' failed. "
;
}
LogType
&
GetLog
()
{
return
log_
;
}
BENCHMARK_NORETURN
~
CheckHandler
()
BENCHMARK_NOEXCEPT_OP
(
false
)
{
log_
<<
std
::
endl
;
CallAbortHandler
();
log_
<<
std
::
endl
;
CallAbortHandler
();
}
CheckHandler
&
operator
=
(
const
CheckHandler
&
)
=
delete
;
CheckHandler
&
operator
=
(
const
CheckHandler
&
)
=
delete
;
CheckHandler
(
const
CheckHandler
&
)
=
delete
;
CheckHandler
()
=
delete
;
private
:
LogType
&
log_
;
private
:
LogType
&
log_
;
};
}
// end namespace internal
}
// end namespace benchmark
}
// 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())
#define CHECK(b) \
(b ? ::benchmark::internal::GetNullLogInstance() \
: ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \
.GetLog())
#else
#
define CHECK(b) ::benchmark::internal::GetNullLogInstance()
#define CHECK(b) ::benchmark::internal::GetNullLogInstance()
#endif
#define CHECK_EQ(a, b) CHECK((a) == (b))
...
...
src/colorprint.cc
View file @
332f677b
...
...
@@ -25,11 +25,11 @@
#include "internal_macros.h"
#ifdef BENCHMARK_OS_WINDOWS
#include <io.h>
#include <Windows.h>
#include <io.h>
#else
#include <unistd.h>
#endif // BENCHMARK_OS_WINDOWS
#endif
// BENCHMARK_OS_WINDOWS
namespace
benchmark
{
namespace
{
...
...
@@ -82,7 +82,7 @@ PlatformColorCode GetPlatformColorCode(LogColor color) {
}
// 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
va_list
args_cp
;
va_copy
(
args_cp
,
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.
CHECK
(
ret
>=
0
);
if
(
ret
==
0
)
// handle empty expansion
if
(
ret
==
0
)
// handle empty expansion
return
{};
else
if
(
static_cast
<
size_t
>
(
ret
)
<
size
)
return
local_buff
;
else
{
// 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
]);
ret
=
std
::
vsnprintf
(
buff
.
get
(),
size
,
msg
,
args
);
CHECK
(
ret
>
0
&&
((
size_t
)
ret
)
<
size
);
...
...
@@ -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_start
(
args
,
msg
);
auto
tmp
=
FormatString
(
msg
,
args
);
...
...
@@ -125,9 +125,10 @@ void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) {
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
((
void
)
out
);
// suppress unused warning
((
void
)
out
);
// suppress unused warning
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
if
(
color_code
)
out
<<
FormatString
(
"
\033
[0;3%sm"
,
color_code
);
out
<<
FormatString
(
fmt
,
args
)
<<
"
\033
[m"
;
#endif
}
bool
IsColorTerminal
()
{
...
...
@@ -182,7 +182,7 @@ bool IsColorTerminal() {
}
return
0
!=
isatty
(
fileno
(
stdout
))
&&
term_supports_color
;
#endif // BENCHMARK_OS_WINDOWS
#endif
// BENCHMARK_OS_WINDOWS
}
}
// end namespace benchmark
src/colorprint.h
View file @
332f677b
...
...
@@ -2,8 +2,8 @@
#define BENCHMARK_COLORPRINT_H_
#include <cstdarg>
#include <string>
#include <iostream>
#include <string>
namespace
benchmark
{
enum
LogColor
{
...
...
@@ -20,7 +20,8 @@ enum LogColor {
std
::
string
FormatString
(
const
char
*
msg
,
va_list
args
);
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
,
...);
// Returns true if stdout appears to be a terminal that supports colored
...
...
src/commandlineflags.cc
View file @
332f677b
...
...
@@ -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
// LONG_MAX or LONG_MIN when the input overflows.)
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, "
<<
"but actually has value
\"
"
<<
str
<<
"
\"
, "
...
...
@@ -95,7 +95,8 @@ static std::string FlagToEnvVar(const char* flag) {
bool
BoolFromEnv
(
const
char
*
flag
,
bool
default_value
)
{
const
std
::
string
env_var
=
FlagToEnvVar
(
flag
);
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
...
...
@@ -209,8 +210,7 @@ bool IsFlag(const char* str, const char* flag) {
}
bool
IsTruthyFlagValue
(
const
std
::
string
&
str
)
{
if
(
str
.
empty
())
return
true
;
if
(
str
.
empty
())
return
true
;
char
ch
=
str
[
0
];
return
isalnum
(
ch
)
&&
!
(
ch
==
'0'
||
ch
==
'f'
||
ch
==
'F'
||
ch
==
'n'
||
ch
==
'N'
);
...
...
src/complexity.cc
View file @
332f677b
...
...
@@ -119,8 +119,7 @@ LeastSq MinimalLeastSq(const std::vector<int>& n,
// this one. If it is oAuto, it will be calculated the best
// fitting curve.
LeastSq
MinimalLeastSq
(
const
std
::
vector
<
int
>&
n
,
const
std
::
vector
<
double
>&
time
,
const
BigO
complexity
)
{
const
std
::
vector
<
double
>&
time
,
const
BigO
complexity
)
{
CHECK_EQ
(
n
.
size
(),
time
.
size
());
CHECK_GE
(
n
.
size
(),
2
);
// Do not compute fitting curve is less than two
// benchmark runs are given
...
...
src/complexity.h
View file @
332f677b
...
...
@@ -47,10 +47,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
// parameter will return the best fitting curve detected.
struct
LeastSq
{
LeastSq
()
:
coef
(
0
.
0
),
rms
(
0
.
0
),
complexity
(
oNone
)
{}
LeastSq
()
:
coef
(
0
.
0
),
rms
(
0
.
0
),
complexity
(
oNone
)
{}
double
coef
;
double
rms
;
...
...
@@ -60,5 +57,5 @@ struct LeastSq {
// Function to return an string for the calculated complexity
std
::
string
GetBigOString
(
BigO
complexity
);
}
// end namespace benchmark
#endif // COMPLEXITY_H_
}
// end namespace benchmark
#endif
// COMPLEXITY_H_
src/console_reporter.cc
View file @
332f677b
...
...
@@ -39,46 +39,45 @@ bool ConsoleReporter::ReportContext(const Context& context) {
#ifdef BENCHMARK_OS_WINDOWS
if
(
color_output_
&&
&
std
::
cout
!=
&
GetOutputStream
())
{
GetErrorStream
()
<<
"Color printing is only supported for stdout on windows."
" Disabling color printing
\n
"
;
color_output_
=
false
;
GetErrorStream
()
<<
"Color printing is only supported for stdout on windows."
" Disabling color printing
\n
"
;
color_output_
=
false
;
}
#endif
std
::
string
str
=
FormatString
(
"%-*s %13s %13s %10s
\n
"
,
static_cast
<
int
>
(
name_field_width_
),
"Benchmark"
,
"Time"
,
"CPU"
,
"Iterations"
);
std
::
string
str
=
FormatString
(
"%-*s %13s %13s %10s
\n
"
,
static_cast
<
int
>
(
name_field_width_
)
,
"Benchmark"
,
"Time"
,
"CPU"
,
"Iterations"
);
GetOutputStream
()
<<
str
<<
std
::
string
(
str
.
length
()
-
1
,
'-'
)
<<
"
\n
"
;
return
true
;
}
void
ConsoleReporter
::
ReportRuns
(
const
std
::
vector
<
Run
>&
reports
)
{
for
(
const
auto
&
run
:
reports
)
PrintRunData
(
run
);
for
(
const
auto
&
run
:
reports
)
PrintRunData
(
run
);
}
static
void
IgnoreColorPrint
(
std
::
ostream
&
out
,
LogColor
,
const
char
*
fmt
,
...)
{
va_list
args
;
va_start
(
args
,
fmt
);
out
<<
FormatString
(
fmt
,
args
);
va_end
(
args
);
static
void
IgnoreColorPrint
(
std
::
ostream
&
out
,
LogColor
,
const
char
*
fmt
,
...)
{
va_list
args
;
va_start
(
args
,
fmt
);
out
<<
FormatString
(
fmt
,
args
);
va_end
(
args
);
}
void
ConsoleReporter
::
PrintRunData
(
const
Run
&
result
)
{
typedef
void
(
PrinterFn
)(
std
::
ostream
&
,
LogColor
,
const
char
*
,
...);
auto
&
Out
=
GetOutputStream
();
PrinterFn
*
printer
=
color_output_
?
(
PrinterFn
*
)
ColorPrintf
:
IgnoreColorPrint
;
PrinterFn
*
printer
=
color_output_
?
(
PrinterFn
*
)
ColorPrintf
:
IgnoreColorPrint
;
auto
name_color
=
(
result
.
report_big_o
||
result
.
report_rms
)
?
COLOR_BLUE
:
COLOR_GREEN
;
printer
(
Out
,
name_color
,
"%-*s "
,
name_field_width_
,
result
.
benchmark_name
.
c_str
());
result
.
benchmark_name
.
c_str
());
if
(
result
.
error_occurred
)
{
printer
(
Out
,
COLOR_RED
,
"ERROR OCCURRED:
\'
%s
\'
"
,
result
.
error_message
.
c_str
());
result
.
error_message
.
c_str
());
printer
(
Out
,
COLOR_DEFAULT
,
"
\n
"
);
return
;
}
...
...
@@ -91,24 +90,24 @@ void ConsoleReporter::PrintRunData(const Run& result) {
// Format items per second
std
::
string
items
;
if
(
result
.
items_per_second
>
0
)
{
items
=
StrCat
(
" "
,
HumanReadableNumber
(
result
.
items_per_second
),
" items/s"
);
}
items
=
StrCat
(
" "
,
HumanReadableNumber
(
result
.
items_per_second
),
" items/s"
);
}
const
double
real_time
=
result
.
GetAdjustedRealTime
();
const
double
cpu_time
=
result
.
GetAdjustedCPUTime
();
if
(
result
.
report_big_o
)
{
std
::
string
big_o
=
GetBigOString
(
result
.
complexity
);
printer
(
Out
,
COLOR_YELLOW
,
"%10.2f %s %10.2f %s "
,
real_time
,
big_o
.
c_str
(),
cpu_time
,
big_o
.
c_str
());
printer
(
Out
,
COLOR_YELLOW
,
"%10.2f %s %10.2f %s "
,
real_time
,
big_o
.
c_str
(),
cpu_time
,
big_o
.
c_str
());
}
else
if
(
result
.
report_rms
)
{
printer
(
Out
,
COLOR_YELLOW
,
"%10.0f %% %10.0f %% "
,
real_time
*
100
,
cpu_time
*
100
);
cpu_time
*
100
);
}
else
{
const
char
*
timeLabel
=
GetTimeUnitString
(
result
.
time_unit
);
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
)
{
...
...
src/csv_reporter.cc
View file @
332f677b
...
...
@@ -31,38 +31,28 @@ namespace benchmark {
namespace
{
std
::
vector
<
std
::
string
>
elements
=
{
"name"
,
"iterations"
,
"real_time"
,
"cpu_time"
,
"time_unit"
,
"bytes_per_second"
,
"items_per_second"
,
"label"
,
"error_occurred"
,
"error_message"
};
"name"
,
"iterations"
,
"real_time"
,
"cpu_time"
,
"time_unit"
,
"bytes_per_second"
,
"items_per_second"
,
"label"
,
"error_occurred"
,
"error_message"
};
}
bool
CSVReporter
::
ReportContext
(
const
Context
&
context
)
{
PrintBasicContext
(
&
GetErrorStream
(),
context
);
std
::
ostream
&
Out
=
GetOutputStream
();
for
(
auto
B
=
elements
.
begin
();
B
!=
elements
.
end
();
)
{
for
(
auto
B
=
elements
.
begin
();
B
!=
elements
.
end
();)
{
Out
<<
*
B
++
;
if
(
B
!=
elements
.
end
())
Out
<<
","
;
if
(
B
!=
elements
.
end
())
Out
<<
","
;
}
Out
<<
"
\n
"
;
return
true
;
}
void
CSVReporter
::
ReportRuns
(
const
std
::
vector
<
Run
>
&
reports
)
{
for
(
const
auto
&
run
:
reports
)
PrintRunData
(
run
);
void
CSVReporter
::
ReportRuns
(
const
std
::
vector
<
Run
>&
reports
)
{
for
(
const
auto
&
run
:
reports
)
PrintRunData
(
run
);
}
void
CSVReporter
::
PrintRunData
(
const
Run
&
run
)
{
void
CSVReporter
::
PrintRunData
(
const
Run
&
run
)
{
std
::
ostream
&
Out
=
GetOutputStream
();
// Field with embedded double-quote characters must be doubled and the field
...
...
src/internal_macros.h
View file @
332f677b
...
...
@@ -4,40 +4,39 @@
#include "benchmark/macros.h"
#ifndef __has_feature
#
define __has_feature(x) 0
#define __has_feature(x) 0
#endif
#if defined(__clang__)
#
define COMPILER_CLANG
#define COMPILER_CLANG
#elif defined(_MSC_VER)
#
define COMPILER_MSVC
#define COMPILER_MSVC
#elif defined(__GNUC__)
#
define COMPILER_GCC
#define COMPILER_GCC
#endif
#if __has_feature(cxx_attributes)
#
define BENCHMARK_NORETURN [[noreturn]]
#define BENCHMARK_NORETURN [[noreturn]]
#elif defined(__GNUC__)
#
define BENCHMARK_NORETURN __attribute__((noreturn))
#define BENCHMARK_NORETURN __attribute__((noreturn))
#elif defined(COMPILER_MSVC)
#
define BENCHMARK_NORETURN __declspec(noreturn)
#define BENCHMARK_NORETURN __declspec(noreturn)
#else
#
define BENCHMARK_NORETURN
#define BENCHMARK_NORETURN
#endif
#if defined(__CYGWIN__)
#
define BENCHMARK_OS_CYGWIN 1
#define BENCHMARK_OS_CYGWIN 1
#elif defined(_WIN32)
#
define BENCHMARK_OS_WINDOWS 1
#define BENCHMARK_OS_WINDOWS 1
#elif defined(__APPLE__)
// TODO(ericwf) This doesn't actually check that it is a Mac OSX system. Just
// that it is an apple system.
#
define BENCHMARK_OS_MACOSX 1
#define BENCHMARK_OS_MACOSX 1
#elif defined(__FreeBSD__)
#
define BENCHMARK_OS_FREEBSD 1
#define BENCHMARK_OS_FREEBSD 1
#elif defined(__linux__)
#
define BENCHMARK_OS_LINUX 1
#define BENCHMARK_OS_LINUX 1
#endif
#endif // BENCHMARK_INTERNAL_MACROS_H_
#endif // BENCHMARK_INTERNAL_MACROS_H_
src/json_reporter.cc
View file @
332f677b
...
...
@@ -47,11 +47,9 @@ std::string FormatKV(std::string const& key, int64_t value) {
return
ss
.
str
();
}
int64_t
RoundDouble
(
double
v
)
{
return
static_cast
<
int64_t
>
(
v
+
0.5
);
}
int64_t
RoundDouble
(
double
v
)
{
return
static_cast
<
int64_t
>
(
v
+
0.5
);
}
}
// end namespace
}
// end namespace
bool
JSONReporter
::
ReportContext
(
const
Context
&
context
)
{
std
::
ostream
&
out
=
GetOutputStream
();
...
...
@@ -66,14 +64,11 @@ bool JSONReporter::ReportContext(const Context& context) {
std
::
string
walltime_value
=
LocalDateTimeString
();
out
<<
indent
<<
FormatKV
(
"date"
,
walltime_value
)
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"num_cpus"
,
static_cast
<
int64_t
>
(
context
.
num_cpus
))
out
<<
indent
<<
FormatKV
(
"num_cpus"
,
static_cast
<
int64_t
>
(
context
.
num_cpus
))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"mhz_per_cpu"
,
RoundDouble
(
context
.
mhz_per_cpu
))
out
<<
indent
<<
FormatKV
(
"mhz_per_cpu"
,
RoundDouble
(
context
.
mhz_per_cpu
))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"cpu_scaling_enabled"
,
context
.
cpu_scaling_enabled
)
out
<<
indent
<<
FormatKV
(
"cpu_scaling_enabled"
,
context
.
cpu_scaling_enabled
)
<<
",
\n
"
;
#if defined(NDEBUG)
...
...
@@ -118,28 +113,20 @@ void JSONReporter::Finalize() {
void
JSONReporter
::
PrintRunData
(
Run
const
&
run
)
{
std
::
string
indent
(
6
,
' '
);
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
<<
FormatKV
(
"
name"
,
run
.
benchmark_name
)
<<
FormatKV
(
"
real_time"
,
RoundDouble
(
run
.
GetAdjustedRealTime
())
)
<<
",
\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
<<
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
));
out
<<
indent
<<
FormatKV
(
"cpu_time"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()));
out
<<
",
\n
"
<<
indent
<<
FormatKV
(
"time_unit"
,
GetTimeUnitString
(
run
.
time_unit
));
}
else
if
(
run
.
report_big_o
)
{
out
<<
indent
<<
FormatKV
(
"cpu_coefficient"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()))
...
...
@@ -147,15 +134,11 @@ void JSONReporter::PrintRunData(Run const& run) {
out
<<
indent
<<
FormatKV
(
"real_coefficient"
,
RoundDouble
(
run
.
GetAdjustedRealTime
()))
<<
",
\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
<<
FormatKV
(
"big_o"
,
GetBigOString
(
run
.
complexity
))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"time_unit"
,
GetTimeUnitString
(
run
.
time_unit
));
}
else
if
(
run
.
report_rms
)
{
out
<<
indent
<<
FormatKV
(
"rms"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()
*
100
))
<<
'%'
;
<<
FormatKV
(
"rms"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()
*
100
))
<<
'%'
;
}
if
(
run
.
bytes_per_second
>
0.0
)
{
out
<<
",
\n
"
...
...
@@ -168,9 +151,7 @@ void JSONReporter::PrintRunData(Run const& run) {
<<
FormatKV
(
"items_per_second"
,
RoundDouble
(
run
.
items_per_second
));
}
if
(
!
run
.
report_label
.
empty
())
{
out
<<
",
\n
"
<<
indent
<<
FormatKV
(
"label"
,
run
.
report_label
);
out
<<
",
\n
"
<<
indent
<<
FormatKV
(
"label"
,
run
.
report_label
);
}
out
<<
'\n'
;
}
...
...
src/log.h
View file @
332f677b
...
...
@@ -63,10 +63,11 @@ inline LogType& GetLogInstanceForLevel(int level) {
return
GetNullLogInstance
();
}
}
// end namespace internal
}
// end namespace benchmark
}
// end namespace internal
}
// end namespace benchmark
#define VLOG(x) (::benchmark::internal::GetLogInstanceForLevel(x) \
<< "-- LOG(" << x << "): ")
#define VLOG(x) \
(::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \
" ")
#endif
\ No newline at end of file
src/mutex.h
View file @
332f677b
#ifndef BENCHMARK_MUTEX_H_
#define BENCHMARK_MUTEX_H_
#include <mutex>
#include <condition_variable>
#include <mutex>
#include "check.h"
// Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers.
#if defined(HAVE_THREAD_SAFETY_ATTRIBUTES)
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
__attribute__((x))
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
// no-op
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define SCOPED_CAPABILITY \
THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define GUARDED_BY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define PT_GUARDED_BY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define ACQUIRED_BEFORE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
...
...
@@ -56,22 +52,18 @@
#define TRY_ACQUIRE_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
#define EXCLUDES(...) \
THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define ASSERT_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define ASSERT_SHARED_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
#define RETURN_CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define NO_THREAD_SAFETY_ANALYSIS \
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
namespace
benchmark
{
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
// -Wthread-safety warning with clang. The standard library types cannot be
// used directly because they do not provided the required annotations.
class
CAPABILITY
(
"mutex"
)
Mutex
{
public
:
class
CAPABILITY
(
"mutex"
)
Mutex
{
public
:
Mutex
()
{}
void
lock
()
ACQUIRE
()
{
mut_
.
lock
();
}
void
unlock
()
RELEASE
()
{
mut_
.
unlock
();
}
std
::
mutex
&
native_handle
()
{
return
mut_
;
}
private
:
std
::
mutex
&
native_handle
()
{
return
mut_
;
}
private
:
std
::
mutex
mut_
;
};
class
SCOPED_CAPABILITY
MutexLock
{
class
SCOPED_CAPABILITY
MutexLock
{
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
()
{}
MutexLockImp
&
native_handle
()
{
return
ml_
;
}
private
:
private
:
MutexLockImp
ml_
;
};
...
...
@@ -161,6 +150,6 @@ class Barrier {
}
};
}
// end namespace benchmark
}
// end namespace benchmark
#endif // BENCHMARK_MUTEX_H_
#endif
// BENCHMARK_MUTEX_H_
src/re.h
View file @
332f677b
...
...
@@ -46,19 +46,19 @@ class Regex {
// Returns whether str matches the compiled regular expression.
bool
Match
(
const
std
::
string
&
str
);
private
:
private
:
bool
init_
;
// Underlying regular expression object
// Underlying regular expression object
#if defined(HAVE_STD_REGEX)
std
::
regex
re_
;
#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)
regex_t
re_
;
#else
#
error No regular expression backend implementation available
#error No regular expression backend implementation available
#endif
};
#if defined(HAVE_STD_REGEX)
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_
;
}
inline
Regex
::~
Regex
()
{
}
inline
Regex
::~
Regex
()
{}
inline
bool
Regex
::
Match
(
const
std
::
string
&
str
)
{
if
(
!
init_
)
{
...
...
src/reporter.cc
View file @
332f677b
...
...
@@ -18,8 +18,8 @@
#include <cstdlib>
#include <iostream>
#include <vector>
#include <tuple>
#include <vector>
#include "check.h"
#include "stat.h"
...
...
@@ -27,49 +27,42 @@
namespace
benchmark
{
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
,
Context
const
&
context
)
{
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
<<
" MHz CPU "
<<
((
context
.
num_cpus
>
1
)
?
"s"
:
""
)
<<
")
\n
"
;
<<
" MHz CPU "
<<
((
context
.
num_cpus
>
1
)
?
"s"
:
""
)
<<
")
\n
"
;
Out
<<
LocalDateTimeString
()
<<
"
\n
"
;
if
(
context
.
cpu_scaling_enabled
)
{
Out
<<
"***WARNING*** CPU scaling is enabled, the benchmark "
"real time measurements may be noisy and will incur extra "
"overhead.
\n
"
;
"real time measurements may be noisy and will incur extra "
"overhead.
\n
"
;
}
#ifndef NDEBUG
Out
<<
"***WARNING*** Library was built as DEBUG. Timings may be "
"affected.
\n
"
;
"affected.
\n
"
;
#endif
}
double
BenchmarkReporter
::
Run
::
GetAdjustedRealTime
()
const
{
double
new_time
=
real_accumulated_time
*
GetTimeUnitMultiplier
(
time_unit
);
if
(
iterations
!=
0
)
new_time
/=
static_cast
<
double
>
(
iterations
);
if
(
iterations
!=
0
)
new_time
/=
static_cast
<
double
>
(
iterations
);
return
new_time
;
}
double
BenchmarkReporter
::
Run
::
GetAdjustedCPUTime
()
const
{
double
new_time
=
cpu_accumulated_time
*
GetTimeUnitMultiplier
(
time_unit
);
if
(
iterations
!=
0
)
new_time
/=
static_cast
<
double
>
(
iterations
);
if
(
iterations
!=
0
)
new_time
/=
static_cast
<
double
>
(
iterations
);
return
new_time
;
}
}
// end namespace benchmark
}
// end namespace benchmark
src/stat.h
View file @
332f677b
...
...
@@ -6,7 +6,6 @@
#include <ostream>
#include <type_traits>
namespace
benchmark
{
template
<
typename
VType
,
typename
NumType
>
...
...
@@ -136,7 +135,7 @@ class Stat1 {
private
:
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."
);
// Let i be the index of the samples provided (using +=)
// and weight[i],value[i] be the data of sample #i
...
...
src/string_util.cc
View file @
332f677b
#include "string_util.h"
#include <array>
#include <cmath>
#include <cstdarg>
#include <
array
>
#include <
cstdio
>
#include <memory>
#include <sstream>
#include <stdio.h>
#include "arraysize.h"
...
...
@@ -27,7 +27,7 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
static
const
int64_t
kUnitsSize
=
arraysize
(
kBigSIUnits
);
}
// end anonymous namespace
}
// end anonymous namespace
void
ToExponentAndMantissa
(
double
val
,
double
thresh
,
int
precision
,
double
one_k
,
std
::
string
*
mantissa
,
...
...
@@ -118,8 +118,7 @@ std::string HumanReadableNumber(double n) {
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
va_list
args_cp
;
va_copy
(
args_cp
,
args
);
...
...
@@ -128,14 +127,14 @@ std::string StringPrintFImp(const char *msg, va_list args)
// allocation guess what the size might be
std
::
array
<
char
,
256
>
local_buff
;
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
);
va_end
(
args_cp
);
// handle empty expansion
if
(
ret
==
0
)
return
std
::
string
{};
if
(
ret
==
0
)
return
std
::
string
{};
if
(
static_cast
<
std
::
size_t
>
(
ret
)
<
size
)
return
std
::
string
(
local_buff
.
data
());
...
...
@@ -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
size
=
static_cast
<
std
::
size_t
>
(
ret
)
+
1
;
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
);
return
std
::
string
(
buff_ptr
.
get
());
}
std
::
string
StringPrintF
(
const
char
*
format
,
...)
{
std
::
string
StringPrintF
(
const
char
*
format
,
...)
{
va_list
args
;
va_start
(
args
,
format
);
std
::
string
tmp
=
StringPrintFImp
(
format
,
args
);
...
...
@@ -160,10 +159,10 @@ std::string StringPrintF(const char* format, ...)
void
ReplaceAll
(
std
::
string
*
str
,
const
std
::
string
&
from
,
const
std
::
string
&
to
)
{
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
);
start
+=
to
.
length
();
}
}
}
// end namespace benchmark
}
// end namespace benchmark
src/string_util.h
View file @
332f677b
#ifndef BENCHMARK_STRING_UTIL_H_
#define BENCHMARK_STRING_UTIL_H_
#include <string>
#include <sstream>
#include <string>
#include <utility>
#include "internal_macros.h"
...
...
@@ -14,23 +14,19 @@ std::string HumanReadableNumber(double n);
std
::
string
StringPrintF
(
const
char
*
format
,
...);
inline
std
::
ostream
&
StringCatImp
(
std
::
ostream
&
out
)
BENCHMARK_NOEXCEPT
{
inline
std
::
ostream
&
StringCatImp
(
std
::
ostream
&
out
)
BENCHMARK_NOEXCEPT
{
return
out
;
}
template
<
class
First
,
class
...
Rest
>
inline
std
::
ostream
&
StringCatImp
(
std
::
ostream
&
out
,
First
&&
f
,
Rest
&&
...
rest
)
{
template
<
class
First
,
class
...
Rest
>
inline
std
::
ostream
&
StringCatImp
(
std
::
ostream
&
out
,
First
&&
f
,
Rest
&&
...
rest
)
{
out
<<
std
::
forward
<
First
>
(
f
);
return
StringCatImp
(
out
,
std
::
forward
<
Rest
>
(
rest
)...);
}
template
<
class
...
Args
>
inline
std
::
string
StrCat
(
Args
&&
...
args
)
{
template
<
class
...
Args
>
inline
std
::
string
StrCat
(
Args
&&
...
args
)
{
std
::
ostringstream
ss
;
StringCatImp
(
ss
,
std
::
forward
<
Args
>
(
args
)...);
return
ss
.
str
();
...
...
@@ -39,6 +35,6 @@ inline std::string StrCat(Args&&... args)
void
ReplaceAll
(
std
::
string
*
str
,
const
std
::
string
&
from
,
const
std
::
string
&
to
);
}
// end namespace benchmark
}
// end namespace benchmark
#endif // BENCHMARK_STRING_UTIL_H_
#endif
// BENCHMARK_STRING_UTIL_H_
src/sysinfo.cc
View file @
332f677b
...
...
@@ -17,13 +17,13 @@
#ifdef BENCHMARK_OS_WINDOWS
#include <Shlwapi.h>
#include <Windows.h>
#include <VersionHelpers.h>
#include <Windows.h>
#else
#include <fcntl.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/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
#include <unistd.h>
#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX
#include <sys/sysctl.h>
...
...
@@ -31,8 +31,8 @@
#endif
#include <cerrno>
#include <cstdio>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
...
...
@@ -126,7 +126,8 @@ void InitializeSystemInfo() {
if
(
fd
==
-
1
)
{
perror
(
pname
);
if
(
!
saw_mhz
)
{
cpuinfo_cycles_per_second
=
static_cast
<
double
>
(
EstimateCyclesPerSecond
());
cpuinfo_cycles_per_second
=
static_cast
<
double
>
(
EstimateCyclesPerSecond
());
}
return
;
}
...
...
@@ -196,7 +197,8 @@ void InitializeSystemInfo() {
cpuinfo_cycles_per_second
=
bogo_clock
;
}
else
{
// 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
)
{
...
...
@@ -238,7 +240,6 @@ void InitializeSystemInfo() {
}
// TODO: also figure out cpuinfo_num_cpus
#elif defined BENCHMARK_OS_WINDOWS
// In NT, read MHz from the registry. If we fail to do so or we're in win9x
// then make a crude estimate.
...
...
@@ -248,15 +249,19 @@ void InitializeSystemInfo() {
SHGetValueA
(
HKEY_LOCAL_MACHINE
,
"HARDWARE
\\
DESCRIPTION
\\
System
\\
CentralProcessor
\\
0"
,
"~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
cpuinfo_cycles_per_second
=
static_cast
<
double
>
(
EstimateCyclesPerSecond
());
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
));
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
// returning "mach time units" per second. the current number of elapsed
...
...
@@ -277,8 +282,8 @@ void InitializeSystemInfo() {
int
num_cpus
=
0
;
size_t
size
=
sizeof
(
num_cpus
);
int
numcpus_name
[]
=
{
CTL_HW
,
HW_NCPU
};
if
(
::
sysctl
(
numcpus_name
,
arraysize
(
numcpus_name
),
&
num_cpus
,
&
size
,
nullptr
,
0
)
==
0
&&
if
(
::
sysctl
(
numcpus_name
,
arraysize
(
numcpus_name
),
&
num_cpus
,
&
size
,
nullptr
,
0
)
==
0
&&
(
size
==
sizeof
(
num_cpus
)))
cpuinfo_num_cpus
=
num_cpus
;
...
...
@@ -316,8 +321,8 @@ bool CpuScalingEnabled() {
// 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.
for
(
int
cpu
=
0
,
num_cpus
=
NumCPUs
();
cpu
<
num_cpus
;
++
cpu
)
{
std
::
string
governor_file
=
StrCat
(
"/sys/devices/system/cpu/cpu"
,
cpu
,
"/cpufreq/scaling_governor"
);
std
::
string
governor_file
=
StrCat
(
"/sys/devices/system/cpu/cpu"
,
cpu
,
"/cpufreq/scaling_governor"
);
FILE
*
file
=
fopen
(
governor_file
.
c_str
(),
"r"
);
if
(
!
file
)
break
;
char
buff
[
16
];
...
...
src/timers.cc
View file @
332f677b
...
...
@@ -92,16 +92,16 @@ double MakeTime(struct timespec const& ts) {
}
#endif
BENCHMARK_NORETURN
static
void
DiagnoseAndExit
(
const
char
*
msg
)
{
std
::
cerr
<<
"ERROR: "
<<
msg
<<
std
::
endl
;
std
::
exit
(
EXIT_FAILURE
);
BENCHMARK_NORETURN
static
void
DiagnoseAndExit
(
const
char
*
msg
)
{
std
::
cerr
<<
"ERROR: "
<<
msg
<<
std
::
endl
;
std
::
exit
(
EXIT_FAILURE
);
}
}
// end namespace
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)
struct
timespec
spec
;
if
(
clock_gettime
(
CLOCK_PROCESS_CPUTIME_ID
,
&
spec
)
==
0
)
...
...
@@ -113,23 +113,23 @@ double ProcessCPUUsage() {
FILETIME
exit_time
;
FILETIME
kernel_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
);
DiagnoseAndExit
(
"GetProccessTimes() failed"
);
#else
struct
rusage
ru
;
if
(
getrusage
(
RUSAGE_SELF
,
&
ru
)
==
0
)
return
MakeTime
(
ru
);
if
(
getrusage
(
RUSAGE_SELF
,
&
ru
)
==
0
)
return
MakeTime
(
ru
);
DiagnoseAndExit
(
"clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed"
);
#endif
}
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)
struct
timespec
ts
;
if
(
clock_gettime
(
CLOCK_THREAD_CPUTIME_ID
,
&
ts
)
==
0
)
return
MakeTime
(
ts
);
if
(
clock_gettime
(
CLOCK_THREAD_CPUTIME_ID
,
&
ts
)
==
0
)
return
MakeTime
(
ts
);
DiagnoseAndExit
(
"clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed"
);
#elif defined(BENCHMARK_OS_WINDOWS)
HANDLE
this_thread
=
GetCurrentThread
();
...
...
@@ -144,8 +144,8 @@ double ThreadCPUUsage() {
mach_msg_type_number_t
count
=
THREAD_BASIC_INFO_COUNT
;
thread_basic_info_data_t
info
;
mach_port_t
thread
=
pthread_mach_thread_np
(
pthread_self
());
if
(
thread_info
(
thread
,
THREAD_BASIC_INFO
,
(
thread_info_t
)
&
info
,
&
count
)
==
KERN_SUCCESS
)
{
if
(
thread_info
(
thread
,
THREAD_BASIC_INFO
,
(
thread_info_t
)
&
info
,
&
count
)
==
KERN_SUCCESS
)
{
return
MakeTime
(
info
);
}
DiagnoseAndExit
(
"ThreadCPUUsage() failed when evaluating thread_info"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment