#include "tile/base/thread/mutex.h"

#include "benchmark/benchmark.h"

namespace tile {
void
Benchmark_MutexLock(benchmark::State &state)
{
    Mutex m;
    while (state.KeepRunning()) {
        (void) m.Lock();
        (void) m.Unlock();
    }
}

void
Benchmark_MutexTryLock(benchmark::State &state)
{
    Mutex m;
    while (state.KeepRunning()) {
        (void) m.TryLock();
        (void) m.Unlock();
    }
}

constexpr auto kRecursiveMutexMaxLockCount = 10000;

void
Benchmark_RecursiveMutexLock(benchmark::State &state)
{
    RecursiveMutex m;
    int count        = 0;
    bool should_lock = true;
    while (state.KeepRunning()) {
        if (should_lock) {
            (void) m.Lock();
            should_lock = ++count < kRecursiveMutexMaxLockCount;
        } else {
            (void) m.Unlock();
            should_lock = --count == 0;
        }
    }
}

void
Benchmark_RecursiveMutexTryLock(benchmark::State &state)
{
    RecursiveMutex m;
    int count        = 0;
    bool should_lock = true;
    while (state.KeepRunning()) {
        if (should_lock) {
            (void) m.TryLock();
            should_lock = ++count < kRecursiveMutexMaxLockCount;
        } else {
            (void) m.Unlock();
            should_lock = --count == 0;
        }
    }
}

BENCHMARK(Benchmark_MutexLock);
BENCHMARK(Benchmark_MutexTryLock);
BENCHMARK(Benchmark_RecursiveMutexLock);
BENCHMARK(Benchmark_RecursiveMutexTryLock);
}// namespace tile
