//===-- tsan_mutex_test.cc ------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_mutex.h"
#include "tsan_mutex.h"
#include "gtest/gtest.h"

namespace __tsan {

template<typename MutexType>
class TestData {
 public:
  explicit TestData(MutexType *mtx)
    : mtx_(mtx) {
    for (int i = 0; i < kSize; i++)
      data_[i] = 0;
  }

  void Write() {
    Lock l(mtx_);
    T v0 = data_[0];
    for (int i = 0; i < kSize; i++) {
      CHECK_EQ(data_[i], v0);
      data_[i]++;
    }
  }

  void Read() {
    ReadLock l(mtx_);
    T v0 = data_[0];
    for (int i = 0; i < kSize; i++) {
      CHECK_EQ(data_[i], v0);
    }
  }

  void Backoff() {
    volatile T data[kSize] = {};
    for (int i = 0; i < kSize; i++) {
      data[i]++;
      CHECK_EQ(data[i], 1);
    }
  }

 private:
  typedef GenericScopedLock<MutexType> Lock;
  static const int kSize = 64;
  typedef u64 T;
  MutexType *mtx_;
  char pad_[kCacheLineSize];
  T data_[kSize];
};

const int kThreads = 8;
const int kWriteRate = 1024;
#if SANITIZER_DEBUG
const int kIters = 16*1024;
#else
const int kIters = 64*1024;
#endif

template<typename MutexType>
static void *write_mutex_thread(void *param) {
  TestData<MutexType> *data = (TestData<MutexType>*)param;
  for (int i = 0; i < kIters; i++) {
    data->Write();
    data->Backoff();
  }
  return 0;
}

template<typename MutexType>
static void *read_mutex_thread(void *param) {
  TestData<MutexType> *data = (TestData<MutexType>*)param;
  for (int i = 0; i < kIters; i++) {
    if ((i % kWriteRate) == 0)
      data->Write();
    else
      data->Read();
    data->Backoff();
  }
  return 0;
}

TEST(Mutex, Write) {
  Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);
  TestData<Mutex> data(&mtx);
  pthread_t threads[kThreads];
  for (int i = 0; i < kThreads; i++)
    pthread_create(&threads[i], 0, write_mutex_thread<Mutex>, &data);
  for (int i = 0; i < kThreads; i++)
    pthread_join(threads[i], 0);
}

TEST(Mutex, ReadWrite) {
  Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);
  TestData<Mutex> data(&mtx);
  pthread_t threads[kThreads];
  for (int i = 0; i < kThreads; i++)
    pthread_create(&threads[i], 0, read_mutex_thread<Mutex>, &data);
  for (int i = 0; i < kThreads; i++)
    pthread_join(threads[i], 0);
}

TEST(Mutex, SpinWrite) {
  SpinMutex mtx;
  TestData<SpinMutex> data(&mtx);
  pthread_t threads[kThreads];
  for (int i = 0; i < kThreads; i++)
    pthread_create(&threads[i], 0, write_mutex_thread<SpinMutex>, &data);
  for (int i = 0; i < kThreads; i++)
    pthread_join(threads[i], 0);
}

}  // namespace __tsan
