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
373cc411
Commit
373cc411
authored
Aug 04, 2014
by
Matt Clarkson
Committed by
Dominic Hamon
Aug 06, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
C++11 concurrency instead of pthread
parent
6b1a6958
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
114 deletions
+64
-114
benchmark.h
include/benchmark/benchmark.h
+2
-2
benchmark.cc
src/benchmark.cc
+52
-77
mutex_lock.h
src/mutex_lock.h
+0
-20
sysinfo.cc
src/sysinfo.cc
+6
-10
CMakeLists.txt
test/CMakeLists.txt
+1
-0
benchmark_test.cc
test/benchmark_test.cc
+3
-5
No files found.
include/benchmark/benchmark.h
View file @
373cc411
...
@@ -139,8 +139,8 @@ BENCHMARK(BM_MultiThreaded)->Threads(4);
...
@@ -139,8 +139,8 @@ BENCHMARK(BM_MultiThreaded)->Threads(4);
#include <functional>
#include <functional>
#include <memory>
#include <memory>
#include <pthread.h>
#include <string>
#include <string>
#include <thread>
#include <vector>
#include <vector>
#include "macros.h"
#include "macros.h"
...
@@ -263,7 +263,7 @@ class State {
...
@@ -263,7 +263,7 @@ class State {
// BenchmarkInstance
// BenchmarkInstance
SharedState
*
shared_
;
SharedState
*
shared_
;
pthread_t
thread_
;
std
::
thread
thread_
;
// Custom label set by the user.
// Custom label set by the user.
std
::
string
label_
;
std
::
string
label_
;
...
...
src/benchmark.cc
View file @
373cc411
...
@@ -16,7 +16,6 @@
...
@@ -16,7 +16,6 @@
#include "benchmark/macros.h"
#include "benchmark/macros.h"
#include "colorprint.h"
#include "colorprint.h"
#include "commandlineflags.h"
#include "commandlineflags.h"
#include "mutex_lock.h"
#include "re.h"
#include "re.h"
#include "sleep.h"
#include "sleep.h"
#include "stat.h"
#include "stat.h"
...
@@ -24,14 +23,15 @@
...
@@ -24,14 +23,15 @@
#include "walltime.h"
#include "walltime.h"
#include <sys/time.h>
#include <sys/time.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <string.h>
#include <algorithm>
#include <algorithm>
#include <atomic>
#include <atomic>
#include <condition_variable>
#include <iostream>
#include <iostream>
#include <memory>
#include <memory>
#include <mutex>
#include <thread>
#include <sstream>
#include <sstream>
DEFINE_string
(
benchmark_filter
,
"."
,
DEFINE_string
(
benchmark_filter
,
"."
,
...
@@ -184,9 +184,9 @@ inline std::string HumanReadableNumber(double n) {
...
@@ -184,9 +184,9 @@ inline std::string HumanReadableNumber(double n) {
// For non-dense Range, intermediate values are powers of kRangeMultiplier.
// For non-dense Range, intermediate values are powers of kRangeMultiplier.
static
const
int
kRangeMultiplier
=
8
;
static
const
int
kRangeMultiplier
=
8
;
static
pthread_mutex_t
benchmark_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
std
::
mutex
benchmark_mutex
;
pthread_mutex_t
starting_mutex
;
std
::
mutex
starting_mutex
;
pthread_cond_t
starting_cv
;
std
::
condition_variable
starting_cv
;
bool
running_benchmark
=
false
;
bool
running_benchmark
=
false
;
...
@@ -342,7 +342,7 @@ BenchmarkFamilies::~BenchmarkFamilies() {
...
@@ -342,7 +342,7 @@ BenchmarkFamilies::~BenchmarkFamilies() {
}
}
int
BenchmarkFamilies
::
AddBenchmark
(
Benchmark
*
family
)
{
int
BenchmarkFamilies
::
AddBenchmark
(
Benchmark
*
family
)
{
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
// This loop attempts to reuse an entry that was previously removed to avoid
// This loop attempts to reuse an entry that was previously removed to avoid
// unncessary growth of the vector.
// unncessary growth of the vector.
for
(
size_t
index
=
0
;
index
<
families_
.
size
();
++
index
)
{
for
(
size_t
index
=
0
;
index
<
families_
.
size
();
++
index
)
{
...
@@ -357,7 +357,7 @@ int BenchmarkFamilies::AddBenchmark(Benchmark* family) {
...
@@ -357,7 +357,7 @@ int BenchmarkFamilies::AddBenchmark(Benchmark* family) {
}
}
void
BenchmarkFamilies
::
RemoveBenchmark
(
int
index
)
{
void
BenchmarkFamilies
::
RemoveBenchmark
(
int
index
)
{
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
families_
[
index
]
=
NULL
;
families_
[
index
]
=
NULL
;
// Don't shrink families_ here, we might be called by the destructor of
// Don't shrink families_ here, we might be called by the destructor of
// BenchmarkFamilies which iterates over the vector.
// BenchmarkFamilies which iterates over the vector.
...
@@ -374,7 +374,7 @@ void BenchmarkFamilies::FindBenchmarks(
...
@@ -374,7 +374,7 @@ void BenchmarkFamilies::FindBenchmarks(
return
;
return
;
}
}
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
for
(
internal
::
Benchmark
*
family
:
families_
)
{
for
(
internal
::
Benchmark
*
family
:
families_
)
{
if
(
family
==
nullptr
)
continue
;
// Family was deleted
if
(
family
==
nullptr
)
continue
;
// Family was deleted
...
@@ -564,21 +564,16 @@ class State::FastClock {
...
@@ -564,21 +564,16 @@ class State::FastClock {
explicit
FastClock
(
Type
type
)
explicit
FastClock
(
Type
type
)
:
type_
(
type
),
:
type_
(
type
),
approx_time_
(
NowMicros
()),
approx_time_
(
NowMicros
()),
bg_done_
(
false
)
{
bg_done_
(
false
),
pthread_cond_init
(
&
bg_cond_
,
nullptr
);
bg_
(
BGThreadWrapper
,
this
)
{
}
pthread_mutex_init
(
&
bg_mutex_
,
nullptr
);
pthread_create
(
&
bg_
,
NULL
,
&
BGThreadWrapper
,
this
);
}
~
FastClock
()
{
~
FastClock
()
{
{
{
mutex_lock
l
(
&
bg_mutex_
);
std
::
unique_lock
<
std
::
mutex
>
l
(
bg_mutex_
);
bg_done_
=
true
;
bg_done_
=
true
;
pthread_cond_signal
(
&
bg_cond_
);
bg_cond_
.
notify_one
(
);
}
}
pthread_join
(
bg_
,
NULL
);
bg_
.
join
();
pthread_mutex_destroy
(
&
bg_mutex_
);
pthread_cond_destroy
(
&
bg_cond_
);
}
}
// Returns true if the current time is guaranteed to be past "when_micros".
// Returns true if the current time is guaranteed to be past "when_micros".
...
@@ -605,7 +600,7 @@ class State::FastClock {
...
@@ -605,7 +600,7 @@ class State::FastClock {
// function starts running - see UseRealTime).
// function starts running - see UseRealTime).
void
InitType
(
Type
type
)
{
void
InitType
(
Type
type
)
{
type_
=
type
;
type_
=
type
;
mutex_lock
l
(
&
bg_mutex_
);
std
::
lock_guard
<
std
::
mutex
>
l
(
bg_mutex_
);
std
::
atomic_store
(
&
approx_time_
,
NowMicros
());
std
::
atomic_store
(
&
approx_time_
,
NowMicros
());
}
}
...
@@ -613,10 +608,9 @@ class State::FastClock {
...
@@ -613,10 +608,9 @@ class State::FastClock {
Type
type_
;
Type
type_
;
std
::
atomic
<
int64_t
>
approx_time_
;
// Last time measurement taken by bg_
std
::
atomic
<
int64_t
>
approx_time_
;
// Last time measurement taken by bg_
bool
bg_done_
;
// This is used to signal background thread to exit
bool
bg_done_
;
// This is used to signal background thread to exit
pthread_t
bg_
;
// Background thread that updates last_time_ once every ms
std
::
mutex
bg_mutex_
;
std
::
condition_variable
bg_cond_
;
pthread_mutex_t
bg_mutex_
;
std
::
thread
bg_
;
// Background thread that updates last_time_ once every ms
pthread_cond_t
bg_cond_
;
static
void
*
BGThreadWrapper
(
void
*
that
)
{
static
void
*
BGThreadWrapper
(
void
*
that
)
{
((
FastClock
*
)
that
)
->
BGThread
();
((
FastClock
*
)
that
)
->
BGThread
();
...
@@ -624,23 +618,11 @@ class State::FastClock {
...
@@ -624,23 +618,11 @@ class State::FastClock {
}
}
void
BGThread
()
{
void
BGThread
()
{
mutex_lock
l
(
&
bg_mutex_
);
std
::
unique_lock
<
std
::
mutex
>
l
(
bg_mutex_
);
while
(
!
bg_done_
)
while
(
!
bg_done_
)
{
{
struct
timeval
tv
;
gettimeofday
(
&
tv
,
nullptr
);
// Set timeout to 1 ms.
// Set timeout to 1 ms.
uint32_t
const
timeout
=
1000
;
bg_cond_
.
wait_for
(
l
,
std
::
chrono
::
milliseconds
(
1
));
struct
timespec
ts
;
ts
.
tv_sec
=
tv
.
tv_sec
+
(
timeout
/
kNumMicrosPerSecond
);
ts
.
tv_nsec
=
(
tv
.
tv_usec
+
(
timeout
%
kNumMicrosPerSecond
))
*
kNumNanosPerMicro
;
ts
.
tv_sec
+=
ts
.
tv_nsec
/
kNumNanosPerSecond
;
ts
.
tv_nsec
%=
kNumNanosPerSecond
;
pthread_cond_timedwait
(
&
bg_cond_
,
&
bg_mutex_
,
&
ts
);
std
::
atomic_store
(
&
approx_time_
,
NowMicros
());
std
::
atomic_store
(
&
approx_time_
,
NowMicros
());
}
}
}
}
...
@@ -693,8 +675,8 @@ struct Benchmark::Instance {
...
@@ -693,8 +675,8 @@ struct Benchmark::Instance {
struct
State
::
SharedState
{
struct
State
::
SharedState
{
const
internal
::
Benchmark
::
Instance
*
instance
;
const
internal
::
Benchmark
::
Instance
*
instance
;
pthread_mutex_t
mu
;
std
::
mutex
mu
;
pthread_cond_t
cond
;
std
::
condition_variable
cond
;
int
starting
;
// Number of threads that have entered STARTING state
int
starting
;
// Number of threads that have entered STARTING state
int
stopping
;
// Number of threads that have entered STOPPING state
int
stopping
;
// Number of threads that have entered STOPPING state
int
exited
;
// Number of threads that have complete exited
int
exited
;
// Number of threads that have complete exited
...
@@ -708,15 +690,8 @@ struct State::SharedState {
...
@@ -708,15 +690,8 @@ struct State::SharedState {
starting
(
0
),
starting
(
0
),
stopping
(
0
),
stopping
(
0
),
exited
(
0
),
exited
(
0
),
threads
(
b
==
nullptr
?
1
:
b
->
threads
)
{
threads
(
b
==
nullptr
?
1
:
b
->
threads
)
{
}
pthread_mutex_init
(
&
mu
,
nullptr
);
pthread_cond_init
(
&
cond
,
nullptr
);
}
~
SharedState
()
{
pthread_cond_destroy
(
&
cond
);
pthread_mutex_destroy
(
&
mu
);
}
DISALLOW_COPY_AND_ASSIGN
(
SharedState
)
DISALLOW_COPY_AND_ASSIGN
(
SharedState
)
};
};
...
@@ -732,7 +707,7 @@ Benchmark::~Benchmark() {
...
@@ -732,7 +707,7 @@ Benchmark::~Benchmark() {
}
}
Benchmark
*
Benchmark
::
Arg
(
int
x
)
{
Benchmark
*
Benchmark
::
Arg
(
int
x
)
{
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
rangeX_
.
push_back
(
x
);
rangeX_
.
push_back
(
x
);
return
this
;
return
this
;
}
}
...
@@ -741,7 +716,7 @@ Benchmark* Benchmark::Range(int start, int limit) {
...
@@ -741,7 +716,7 @@ Benchmark* Benchmark::Range(int start, int limit) {
std
::
vector
<
int
>
arglist
;
std
::
vector
<
int
>
arglist
;
AddRange
(
&
arglist
,
start
,
limit
,
kRangeMultiplier
);
AddRange
(
&
arglist
,
start
,
limit
,
kRangeMultiplier
);
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
for
(
size_t
i
=
0
;
i
<
arglist
.
size
();
++
i
)
rangeX_
.
push_back
(
arglist
[
i
]);
for
(
size_t
i
=
0
;
i
<
arglist
.
size
();
++
i
)
rangeX_
.
push_back
(
arglist
[
i
]);
return
this
;
return
this
;
}
}
...
@@ -749,13 +724,13 @@ Benchmark* Benchmark::Range(int start, int limit) {
...
@@ -749,13 +724,13 @@ Benchmark* Benchmark::Range(int start, int limit) {
Benchmark
*
Benchmark
::
DenseRange
(
int
start
,
int
limit
)
{
Benchmark
*
Benchmark
::
DenseRange
(
int
start
,
int
limit
)
{
CHECK_GE
(
start
,
0
);
CHECK_GE
(
start
,
0
);
CHECK_LE
(
start
,
limit
);
CHECK_LE
(
start
,
limit
);
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
for
(
int
arg
=
start
;
arg
<=
limit
;
++
arg
)
rangeX_
.
push_back
(
arg
);
for
(
int
arg
=
start
;
arg
<=
limit
;
++
arg
)
rangeX_
.
push_back
(
arg
);
return
this
;
return
this
;
}
}
Benchmark
*
Benchmark
::
ArgPair
(
int
x
,
int
y
)
{
Benchmark
*
Benchmark
::
ArgPair
(
int
x
,
int
y
)
{
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
rangeX_
.
push_back
(
x
);
rangeX_
.
push_back
(
x
);
rangeY_
.
push_back
(
y
);
rangeY_
.
push_back
(
y
);
return
this
;
return
this
;
...
@@ -766,7 +741,7 @@ Benchmark* Benchmark::RangePair(int lo1, int hi1, int lo2, int hi2) {
...
@@ -766,7 +741,7 @@ Benchmark* Benchmark::RangePair(int lo1, int hi1, int lo2, int hi2) {
AddRange
(
&
arglist1
,
lo1
,
hi1
,
kRangeMultiplier
);
AddRange
(
&
arglist1
,
lo1
,
hi1
,
kRangeMultiplier
);
AddRange
(
&
arglist2
,
lo2
,
hi2
,
kRangeMultiplier
);
AddRange
(
&
arglist2
,
lo2
,
hi2
,
kRangeMultiplier
);
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
rangeX_
.
resize
(
arglist1
.
size
());
rangeX_
.
resize
(
arglist1
.
size
());
std
::
copy
(
arglist1
.
begin
(),
arglist1
.
end
(),
rangeX_
.
begin
());
std
::
copy
(
arglist1
.
begin
(),
arglist1
.
end
(),
rangeX_
.
begin
());
rangeY_
.
resize
(
arglist2
.
size
());
rangeY_
.
resize
(
arglist2
.
size
());
...
@@ -781,7 +756,7 @@ Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
...
@@ -781,7 +756,7 @@ Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
Benchmark
*
Benchmark
::
Threads
(
int
t
)
{
Benchmark
*
Benchmark
::
Threads
(
int
t
)
{
CHECK_GT
(
t
,
0
);
CHECK_GT
(
t
,
0
);
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
thread_counts_
.
push_back
(
t
);
thread_counts_
.
push_back
(
t
);
return
this
;
return
this
;
}
}
...
@@ -790,13 +765,13 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
...
@@ -790,13 +765,13 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
CHECK_GT
(
min_threads
,
0
);
CHECK_GT
(
min_threads
,
0
);
CHECK_GE
(
max_threads
,
min_threads
);
CHECK_GE
(
max_threads
,
min_threads
);
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
AddRange
(
&
thread_counts_
,
min_threads
,
max_threads
,
2
);
AddRange
(
&
thread_counts_
,
min_threads
,
max_threads
,
2
);
return
this
;
return
this
;
}
}
Benchmark
*
Benchmark
::
ThreadPerCpu
()
{
Benchmark
*
Benchmark
::
ThreadPerCpu
()
{
mutex_lock
l
(
&
benchmark_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
benchmark_mutex
);
thread_counts_
.
push_back
(
NumCPUs
());
thread_counts_
.
push_back
(
NumCPUs
());
return
this
;
return
this
;
}
}
...
@@ -1017,13 +992,13 @@ bool State::KeepRunning() {
...
@@ -1017,13 +992,13 @@ bool State::KeepRunning() {
}
}
if
(
!
ret
&&
shared_
->
threads
>
1
&&
thread_index
==
0
){
if
(
!
ret
&&
shared_
->
threads
>
1
&&
thread_index
==
0
){
mutex_lock
l
(
&
shared_
->
mu
);
std
::
unique_lock
<
std
::
mutex
>
l
(
shared_
->
mu
);
// Block until all other threads have exited. We can then safely cleanup
// Block until all other threads have exited. We can then safely cleanup
// without other threads continuing to access shared variables inside the
// without other threads continuing to access shared variables inside the
// user-provided run function.
// user-provided run function.
while
(
shared_
->
exited
<
shared_
->
threads
-
1
)
{
while
(
shared_
->
exited
<
shared_
->
threads
-
1
)
{
pthread_cond_wait
(
&
shared_
->
cond
,
&
shared_
->
mu
);
shared_
->
cond
.
wait
(
l
);
}
}
}
}
...
@@ -1045,19 +1020,19 @@ void State::ResumeTiming() {
...
@@ -1045,19 +1020,19 @@ void State::ResumeTiming() {
void
State
::
SetBytesProcessed
(
int64_t
bytes
)
{
void
State
::
SetBytesProcessed
(
int64_t
bytes
)
{
CHECK_EQ
(
STATE_STOPPED
,
state_
);
CHECK_EQ
(
STATE_STOPPED
,
state_
);
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
stats_
->
bytes_processed
=
bytes
;
stats_
->
bytes_processed
=
bytes
;
}
}
void
State
::
SetItemsProcessed
(
int64_t
items
)
{
void
State
::
SetItemsProcessed
(
int64_t
items
)
{
CHECK_EQ
(
STATE_STOPPED
,
state_
);
CHECK_EQ
(
STATE_STOPPED
,
state_
);
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
stats_
->
items_processed
=
items
;
stats_
->
items_processed
=
items
;
}
}
void
State
::
SetLabel
(
const
std
::
string
&
label
)
{
void
State
::
SetLabel
(
const
std
::
string
&
label
)
{
CHECK_EQ
(
STATE_STOPPED
,
state_
);
CHECK_EQ
(
STATE_STOPPED
,
state_
);
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
shared_
->
label
=
label
;
shared_
->
label
=
label
;
}
}
...
@@ -1083,7 +1058,7 @@ int State::range_y() const {
...
@@ -1083,7 +1058,7 @@ int State::range_y() const {
bool
State
::
StartRunning
()
{
bool
State
::
StartRunning
()
{
bool
last_thread
=
false
;
bool
last_thread
=
false
;
{
{
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
CHECK_EQ
(
state_
,
STATE_INITIAL
);
CHECK_EQ
(
state_
,
STATE_INITIAL
);
state_
=
STATE_STARTING
;
state_
=
STATE_STARTING
;
is_continuation_
=
false
;
is_continuation_
=
false
;
...
@@ -1096,12 +1071,12 @@ bool State::StartRunning() {
...
@@ -1096,12 +1071,12 @@ bool State::StartRunning() {
clock_
->
InitType
(
use_real_time
?
FastClock
::
REAL_TIME
clock_
->
InitType
(
use_real_time
?
FastClock
::
REAL_TIME
:
FastClock
::
CPU_TIME
);
:
FastClock
::
CPU_TIME
);
{
{
mutex_lock
l
(
&
starting_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
starting_mutex
);
pthread_cond_broadcast
(
&
starting_cv
);
starting_cv
.
notify_all
(
);
}
}
}
else
{
}
else
{
mutex_lock
l
(
&
starting_mutex
);
std
::
unique_lock
<
std
::
mutex
>
l
(
starting_mutex
);
pthread_cond_wait
(
&
starting_cv
,
&
starting_mutex
);
starting_cv
.
wait
(
l
);
}
}
CHECK_EQ
(
state_
,
STATE_STARTING
);
CHECK_EQ
(
state_
,
STATE_STARTING
);
state_
=
STATE_RUNNING
;
state_
=
STATE_RUNNING
;
...
@@ -1161,7 +1136,7 @@ bool State::FinishInterval() {
...
@@ -1161,7 +1136,7 @@ bool State::FinishInterval() {
bool
keep_going
=
false
;
bool
keep_going
=
false
;
{
{
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
// Either replace the last or add a new data point.
// Either replace the last or add a new data point.
if
(
is_continuation_
)
if
(
is_continuation_
)
...
@@ -1198,7 +1173,7 @@ bool State::FinishInterval() {
...
@@ -1198,7 +1173,7 @@ bool State::FinishInterval() {
}
}
bool
State
::
MaybeStop
()
{
bool
State
::
MaybeStop
()
{
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
if
(
shared_
->
stopping
<
shared_
->
threads
)
{
if
(
shared_
->
stopping
<
shared_
->
threads
)
{
CHECK_EQ
(
state_
,
STATE_STOPPING
);
CHECK_EQ
(
state_
,
STATE_STOPPING
);
return
true
;
return
true
;
...
@@ -1211,16 +1186,20 @@ void State::Run() {
...
@@ -1211,16 +1186,20 @@ void State::Run() {
stats_
->
Reset
();
stats_
->
Reset
();
shared_
->
instance
->
bm
->
function_
(
*
this
);
shared_
->
instance
->
bm
->
function_
(
*
this
);
{
{
mutex_lock
l
(
&
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
shared_
->
mu
);
shared_
->
stats
.
Add
(
*
stats_
);
shared_
->
stats
.
Add
(
*
stats_
);
}
}
}
}
void
State
::
RunAsThread
()
{
void
State
::
RunAsThread
()
{
CHECK_EQ
(
0
,
pthread_create
(
&
thread_
,
nullptr
,
&
State
::
RunWrapper
,
this
)
);
thread_
=
std
::
thread
(
State
::
RunWrapper
,
this
);
}
}
void
State
::
Wait
()
{
CHECK_EQ
(
0
,
pthread_join
(
thread_
,
nullptr
));
}
void
State
::
Wait
()
{
if
(
thread_
.
joinable
())
{
thread_
.
join
();
}
}
// static
// static
void
*
State
::
RunWrapper
(
void
*
arg
)
{
void
*
State
::
RunWrapper
(
void
*
arg
)
{
...
@@ -1228,14 +1207,14 @@ void* State::RunWrapper(void* arg) {
...
@@ -1228,14 +1207,14 @@ void* State::RunWrapper(void* arg) {
CHECK
(
that
!=
nullptr
);
CHECK
(
that
!=
nullptr
);
that
->
Run
();
that
->
Run
();
mutex_lock
l
(
&
that
->
shared_
->
mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
that
->
shared_
->
mu
);
that
->
shared_
->
exited
++
;
that
->
shared_
->
exited
++
;
if
(
that
->
thread_index
>
0
&&
if
(
that
->
thread_index
>
0
&&
that
->
shared_
->
exited
==
that
->
shared_
->
threads
-
1
)
{
that
->
shared_
->
exited
==
that
->
shared_
->
threads
-
1
)
{
// All threads but thread 0 have exited the user-provided run function.
// All threads but thread 0 have exited the user-provided run function.
// Thread 0 can now wake up and exit.
// Thread 0 can now wake up and exit.
pthread_cond_signal
(
&
that
->
shared_
->
cond
);
that
->
shared_
->
cond
.
notify_one
(
);
}
}
return
nullptr
;
return
nullptr
;
...
@@ -1301,13 +1280,9 @@ void RunSpecifiedBenchmarks(const BenchmarkReporter* reporter /*= nullptr*/) {
...
@@ -1301,13 +1280,9 @@ void RunSpecifiedBenchmarks(const BenchmarkReporter* reporter /*= nullptr*/) {
internal
::
ConsoleReporter
default_reporter
;
internal
::
ConsoleReporter
default_reporter
;
internal
::
RunMatchingBenchmarks
(
internal
::
RunMatchingBenchmarks
(
spec
,
reporter
==
nullptr
?
&
default_reporter
:
reporter
);
spec
,
reporter
==
nullptr
?
&
default_reporter
:
reporter
);
pthread_cond_destroy
(
&
starting_cv
);
pthread_mutex_destroy
(
&
starting_mutex
);
}
}
void
Initialize
(
int
*
argc
,
const
char
**
argv
)
{
void
Initialize
(
int
*
argc
,
const
char
**
argv
)
{
pthread_mutex_init
(
&
starting_mutex
,
nullptr
);
pthread_cond_init
(
&
starting_cv
,
nullptr
);
walltime
::
Initialize
();
walltime
::
Initialize
();
internal
::
ParseCommandLineFlags
(
argc
,
argv
);
internal
::
ParseCommandLineFlags
(
argc
,
argv
);
internal
::
Benchmark
::
MeasureOverhead
();
internal
::
Benchmark
::
MeasureOverhead
();
...
...
src/mutex_lock.h
deleted
100644 → 0
View file @
6b1a6958
#ifndef BENCHMARK_MUTEX_LOCK_H_
#define BENCHMARK_MUTEX_LOCK_H_
#include <pthread.h>
namespace
benchmark
{
class
mutex_lock
{
public
:
explicit
mutex_lock
(
pthread_mutex_t
*
mu
)
:
mu_
(
mu
)
{
pthread_mutex_lock
(
mu_
);
}
~
mutex_lock
()
{
pthread_mutex_unlock
(
mu_
);
}
private
:
pthread_mutex_t
*
mu_
;
};
}
// end namespace benchmark
#endif // BENCHMARK_MUTEX_LOCK_H_
src/sysinfo.cc
View file @
373cc411
...
@@ -16,7 +16,6 @@
...
@@ -16,7 +16,6 @@
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
...
@@ -28,18 +27,18 @@
...
@@ -28,18 +27,18 @@
#include <iostream>
#include <iostream>
#include <limits>
#include <limits>
#include <mutex>
#include "benchmark/macros.h"
#include "benchmark/macros.h"
#include "cycleclock.h"
#include "cycleclock.h"
#include "mutex_lock.h"
#include "sleep.h"
#include "sleep.h"
namespace
benchmark
{
namespace
benchmark
{
namespace
{
namespace
{
pthread_once_t
cpuinfo_init
=
PTHREAD_ONCE_INIT
;
std
::
once_flag
cpuinfo_init
;
double
cpuinfo_cycles_per_second
=
1.0
;
double
cpuinfo_cycles_per_second
=
1.0
;
int
cpuinfo_num_cpus
=
1
;
// Conservative guess
int
cpuinfo_num_cpus
=
1
;
// Conservative guess
pthread_mutex_t
cputimens_mutex
;
std
::
mutex
cputimens_mutex
;
#if !defined OS_MACOSX
#if !defined OS_MACOSX
const
int64_t
estimate_time_ms
=
1000
;
const
int64_t
estimate_time_ms
=
1000
;
...
@@ -76,9 +75,6 @@ bool ReadIntFromFile(const char* file, int* value) {
...
@@ -76,9 +75,6 @@ bool ReadIntFromFile(const char* file, int* value) {
#endif
#endif
void
InitializeSystemInfo
()
{
void
InitializeSystemInfo
()
{
// TODO: destroy this
pthread_mutex_init
(
&
cputimens_mutex
,
NULL
);
#if defined OS_LINUX || defined OS_CYGWIN
#if defined OS_LINUX || defined OS_CYGWIN
char
line
[
1024
];
char
line
[
1024
];
char
*
err
;
char
*
err
;
...
@@ -315,7 +311,7 @@ static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
...
@@ -315,7 +311,7 @@ static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
double
MyCPUUsage
()
{
double
MyCPUUsage
()
{
{
{
mutex_lock
l
(
&
cputimens_mutex
);
std
::
lock_guard
<
std
::
mutex
>
l
(
cputimens_mutex
);
static
bool
use_cputime_ns
=
true
;
static
bool
use_cputime_ns
=
true
;
if
(
use_cputime_ns
)
{
if
(
use_cputime_ns
)
{
double
value
;
double
value
;
...
@@ -344,12 +340,12 @@ double ChildrenCPUUsage() {
...
@@ -344,12 +340,12 @@ double ChildrenCPUUsage() {
#endif // OS_WINDOWS
#endif // OS_WINDOWS
double
CyclesPerSecond
(
void
)
{
double
CyclesPerSecond
(
void
)
{
pthread_once
(
&
cpuinfo_init
,
&
InitializeSystemInfo
);
std
::
call_once
(
cpuinfo_init
,
InitializeSystemInfo
);
return
cpuinfo_cycles_per_second
;
return
cpuinfo_cycles_per_second
;
}
}
int
NumCPUs
(
void
)
{
int
NumCPUs
(
void
)
{
pthread_once
(
&
cpuinfo_init
,
&
InitializeSystemInfo
);
std
::
call_once
(
cpuinfo_init
,
InitializeSystemInfo
);
return
cpuinfo_num_cpus
;
return
cpuinfo_num_cpus
;
}
}
}
// end namespace benchmark
}
// end namespace benchmark
test/CMakeLists.txt
View file @
373cc411
# Demonstration executable
# Demonstration executable
add_executable
(
benchmark_test benchmark_test.cc
)
add_executable
(
benchmark_test benchmark_test.cc
)
target_link_libraries
(
benchmark_test benchmark
${
CMAKE_THREAD_LIBS_INIT
}
)
target_link_libraries
(
benchmark_test benchmark
${
CMAKE_THREAD_LIBS_INIT
}
)
add_test
(
benchmark benchmark_test
)
# Test harness for regex wrapper
# Test harness for regex wrapper
add_executable
(
re_test
${
RE_FILES
}
"re_test.cc"
)
add_executable
(
re_test
${
RE_FILES
}
"re_test.cc"
)
...
...
test/benchmark_test.cc
View file @
373cc411
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include <limits>
#include <limits>
#include <list>
#include <list>
#include <map>
#include <map>
#include <mutex>
#include <set>
#include <set>
#include <sstream>
#include <sstream>
#include <vector>
#include <vector>
...
@@ -34,7 +35,7 @@ std::set<int> ConstructRandomSet(int size) {
...
@@ -34,7 +35,7 @@ std::set<int> ConstructRandomSet(int size) {
return
s
;
return
s
;
}
}
pthread_mutex_t
test_vector_mu
;
std
::
mutex
test_vector_mu
;
std
::
vector
<
int
>*
test_vector
=
nullptr
;
std
::
vector
<
int
>*
test_vector
=
nullptr
;
}
// end namespace
}
// end namespace
...
@@ -113,23 +114,20 @@ BENCHMARK(BM_StringCompare)->Range(1, 1<<20);
...
@@ -113,23 +114,20 @@ BENCHMARK(BM_StringCompare)->Range(1, 1<<20);
static
void
BM_SetupTeardown
(
benchmark
::
State
&
state
)
{
static
void
BM_SetupTeardown
(
benchmark
::
State
&
state
)
{
if
(
state
.
thread_index
==
0
)
{
if
(
state
.
thread_index
==
0
)
{
pthread_mutex_init
(
&
test_vector_mu
,
nullptr
);
// No need to lock test_vector_mu here as this is running single-threaded.
// No need to lock test_vector_mu here as this is running single-threaded.
test_vector
=
new
std
::
vector
<
int
>
();
test_vector
=
new
std
::
vector
<
int
>
();
}
}
int
i
=
0
;
int
i
=
0
;
while
(
state
.
KeepRunning
())
{
while
(
state
.
KeepRunning
())
{
pthread_mutex_lock
(
&
test_vector_mu
);
std
::
lock_guard
<
std
::
mutex
>
l
(
test_vector_mu
);
if
(
i
%
2
==
0
)
if
(
i
%
2
==
0
)
test_vector
->
push_back
(
i
);
test_vector
->
push_back
(
i
);
else
else
test_vector
->
pop_back
();
test_vector
->
pop_back
();
pthread_mutex_unlock
(
&
test_vector_mu
);
++
i
;
++
i
;
}
}
if
(
state
.
thread_index
==
0
)
{
if
(
state
.
thread_index
==
0
)
{
delete
test_vector
;
delete
test_vector
;
pthread_mutex_destroy
(
&
test_vector_mu
);
}
}
}
}
BENCHMARK
(
BM_SetupTeardown
)
->
ThreadPerCpu
();
BENCHMARK
(
BM_SetupTeardown
)
->
ThreadPerCpu
();
...
...
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