24 #include "benchmark/benchmark.h" 28 void BM_Mutex(benchmark::State& state) {
30 for (
auto _ : state) {
34 BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu();
36 static void DelayNs(int64_t ns,
int*
data) {
41 benchmark::DoNotOptimize(*data);
45 template <
typename MutexType>
48 explicit RaiiLocker(MutexType* mu) : mu_(mu) { mu_->Lock(); }
49 ~RaiiLocker() { mu_->Unlock(); }
55 class RaiiLocker<
std::mutex> {
57 explicit RaiiLocker(std::mutex* mu) : mu_(mu) { mu_->lock(); }
58 ~RaiiLocker() { mu_->unlock(); }
63 template <
typename MutexType>
64 void BM_Contended(benchmark::State& state) {
69 static auto* shared =
new Shared;
71 for (
auto _ : state) {
82 DelayNs(100 * state.threads, &local);
83 RaiiLocker<MutexType> locker(&shared->mu);
84 DelayNs(state.range(0), &shared->data);
138 BENCHMARK_TEMPLATE(BM_Contended, std::mutex)
169 void BM_ConditionWaiters(benchmark::State& state) {
170 int num_classes = state.range(0);
171 int num_waiters = state.range(1);
177 static_cast<bool (*)(
int*)
>([](
int*
v) {
return *v == 0; }), p));
182 if (num_classes == 0) {
184 num_classes = num_waiters;
189 std::vector<int> equivalence_classes(num_classes, 1);
194 for (
int i = 0;
i < num_waiters;
i++) {
197 pool.Schedule([&,
i] {
198 Helper::Waiter(&init, &mu, &equivalence_classes[
i % num_classes]);
203 for (
auto _ : state) {
209 for (
int i = 0;
i < num_classes;
i++) {
210 equivalence_classes[
i] = 0;
216 #if defined(__linux__) && !defined(THREAD_SANITIZER) 217 constexpr
int kMaxConditionWaiters = 8192;
219 constexpr
int kMaxConditionWaiters = 1024;
221 BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);
void LockWhen(const Condition &cond) EXCLUSIVE_LOCK_FUNCTION()
static double Frequency()
void Unlock() UNLOCK_FUNCTION()
static char data[kDataSize]
void Lock() EXCLUSIVE_LOCK_FUNCTION()