Commit 373cc411 by Matt Clarkson Committed by Dominic Hamon

C++11 concurrency instead of pthread

parent 6b1a6958
...@@ -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_;
......
...@@ -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();
......
#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_
...@@ -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
# 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")
......
...@@ -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();
......
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