/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <pthread.h>

#include <benchmark/benchmark.h>
#include "util.h"

// Stop GCC optimizing out our pure function.
/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;

static void BM_pthread_self(benchmark::State& state) {
  while (state.KeepRunning()) {
    pthread_self_fp();
  }
}
BIONIC_BENCHMARK(BM_pthread_self);

static void BM_pthread_getspecific(benchmark::State& state) {
  pthread_key_t key;
  pthread_key_create(&key, nullptr);

  while (state.KeepRunning()) {
    pthread_getspecific(key);
  }

  pthread_key_delete(key);
}
BIONIC_BENCHMARK(BM_pthread_getspecific);

static void BM_pthread_setspecific(benchmark::State& state) {
  pthread_key_t key;
  pthread_key_create(&key, nullptr);

  while (state.KeepRunning()) {
    pthread_setspecific(key, nullptr);
  }

  pthread_key_delete(key);
}
BIONIC_BENCHMARK(BM_pthread_setspecific);

static void NoOpPthreadOnceInitFunction() {}

static void BM_pthread_once(benchmark::State& state) {
  static pthread_once_t once = PTHREAD_ONCE_INIT;
  pthread_once(&once, NoOpPthreadOnceInitFunction);

  while (state.KeepRunning()) {
    pthread_once(&once, NoOpPthreadOnceInitFunction);
  }
}
BIONIC_BENCHMARK(BM_pthread_once);

static void BM_pthread_mutex_lock(benchmark::State& state) {
  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

  while (state.KeepRunning()) {
    pthread_mutex_lock(&mutex);
    pthread_mutex_unlock(&mutex);
  }
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock);

static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
  pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

  while (state.KeepRunning()) {
    pthread_mutex_lock(&mutex);
    pthread_mutex_unlock(&mutex);
  }
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);

static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
  pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

  while (state.KeepRunning()) {
    pthread_mutex_lock(&mutex);
    pthread_mutex_unlock(&mutex);
  }
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);

namespace {
struct PIMutex {
  pthread_mutex_t mutex;

  explicit PIMutex(int type) {
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, type);
    pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
    pthread_mutex_init(&mutex, &attr);
    pthread_mutexattr_destroy(&attr);
  }

  ~PIMutex() {
    pthread_mutex_destroy(&mutex);
  }
};
}

static void BM_pthread_mutex_lock_PI(benchmark::State& state) {
  PIMutex m(PTHREAD_MUTEX_NORMAL);

  while (state.KeepRunning()) {
    pthread_mutex_lock(&m.mutex);
    pthread_mutex_unlock(&m.mutex);
  }
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_PI);

static void BM_pthread_mutex_lock_ERRORCHECK_PI(benchmark::State& state) {
  PIMutex m(PTHREAD_MUTEX_ERRORCHECK);

  while (state.KeepRunning()) {
    pthread_mutex_lock(&m.mutex);
    pthread_mutex_unlock(&m.mutex);
  }
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK_PI);

static void BM_pthread_mutex_lock_RECURSIVE_PI(benchmark::State& state) {
  PIMutex m(PTHREAD_MUTEX_RECURSIVE);

  while (state.KeepRunning()) {
    pthread_mutex_lock(&m.mutex);
    pthread_mutex_unlock(&m.mutex);
  }
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI);

static void BM_pthread_rwlock_read(benchmark::State& state) {
  pthread_rwlock_t lock;
  pthread_rwlock_init(&lock, nullptr);

  while (state.KeepRunning()) {
    pthread_rwlock_rdlock(&lock);
    pthread_rwlock_unlock(&lock);
  }

  pthread_rwlock_destroy(&lock);
}
BIONIC_BENCHMARK(BM_pthread_rwlock_read);

static void BM_pthread_rwlock_write(benchmark::State& state) {
  pthread_rwlock_t lock;
  pthread_rwlock_init(&lock, nullptr);

  while (state.KeepRunning()) {
    pthread_rwlock_wrlock(&lock);
    pthread_rwlock_unlock(&lock);
  }

  pthread_rwlock_destroy(&lock);
}
BIONIC_BENCHMARK(BM_pthread_rwlock_write);

static void* IdleThread(void*) {
  return nullptr;
}

static void BM_pthread_create(benchmark::State& state) {
  while (state.KeepRunning()) {
    pthread_t thread;
    pthread_create(&thread, nullptr, IdleThread, nullptr);
    state.PauseTiming();
    pthread_join(thread, nullptr);
    state.ResumeTiming();
  }
}
BIONIC_BENCHMARK(BM_pthread_create);

static void* RunThread(void*) {
  return nullptr;
}

static void BM_pthread_create_and_run(benchmark::State& state) {
  while (state.KeepRunning()) {
    pthread_t thread;
    pthread_create(&thread, nullptr, RunThread, &state);
    pthread_join(thread, nullptr);
  }
}
BIONIC_BENCHMARK(BM_pthread_create_and_run);

static void* ExitThread(void*) {
  pthread_exit(nullptr);
}

static void BM_pthread_exit_and_join(benchmark::State& state) {
  while (state.KeepRunning()) {
    pthread_t thread;
    pthread_create(&thread, nullptr, ExitThread, nullptr);
    pthread_join(thread, nullptr);
  }
}
BIONIC_BENCHMARK(BM_pthread_exit_and_join);

static void BM_pthread_key_create(benchmark::State& state) {
  while (state.KeepRunning()) {
    pthread_key_t key;
    pthread_key_create(&key, nullptr);

    state.PauseTiming();
    pthread_key_delete(key);
    state.ResumeTiming();
  }
}
BIONIC_BENCHMARK(BM_pthread_key_create);

static void BM_pthread_key_delete(benchmark::State& state) {
  while (state.KeepRunning()) {
    state.PauseTiming();
    pthread_key_t key;
    pthread_key_create(&key, nullptr);
    state.ResumeTiming();

    pthread_key_delete(key);
  }
}
BIONIC_BENCHMARK(BM_pthread_key_delete);
