// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/mutex.h"

#ifdef OS_WIN
#include <Windows.h>
#else
#include <pthread.h>
#endif

#ifdef OS_MACOSX
#include <libkern/OSAtomic.h>
#endif  // OS_MACOSX

#include "base/port.h"
#include "base/util.h"
#include "base/win_util.h"

#if defined(OS_WIN)
// We do not use pthread on Windows
#elif defined(OS_ANDROID)
// pthread rwlock is supported since API Level 9.
// Currently minimum API Level is 7 so we cannot use it.
// Note that we cannot use __ANDROID_API__ macro in above condition
// because it is equal to target API Level, which is greater than
// min sdk level. Causes runtime crash.
#elif defined(__native_client__)
// TODO(team): Consider to use glibc rwlock.
#else
#define MOZC_PTHREAD_HAS_READER_WRITER_LOCK
#endif

namespace mozc {

// Wrapper for Windows InterlockedCompareExchange
namespace {
#ifdef OS_LINUX
// Linux doesn't provide InterlockedCompareExchange-like function.
inline int InterlockedCompareExchange(volatile int *target,
                                      int new_value,
                                      int old_value) {
  // TODO(yusukes): For now, we use the architecture-neutral implementation,
  // but I believe it's definitely better to port Chromium's singleton to Mozc.
  // The implementation should be much faster and supports ARM Linux.
  // http://src.chromium.org/viewvc/chrome/trunk/src/base/singleton.h

  static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&lock);
  int result = *target;
  if (result == old_value) {
    *target = new_value;
  }
  pthread_mutex_unlock(&lock);
  return result;
}
#endif  // OS_LINUX

// Use OSAtomicCompareAndSwapInt on Mac OSX
// http://developer.apple.com/iphone/library/documentation/
// system/conceptual/manpages_iphoneos/man3/OSAtomicCompareAndSwapInt.3.html
// TODO(taku): should we use OSAtomicCompareAndSwapIntBarrier?
#ifdef OS_MACOSX
inline int InterlockedCompareExchange(volatile int *target,
                                      int new_value,
                                      int old_value) {
  return OSAtomicCompareAndSwapInt(old_value, new_value, target)
      ? old_value : *target;
}
#endif  // OX_MACOSX

}  // namespace

#ifdef OS_WIN  // Hereafter, we have Win32 implementations
namespace {

template <typename T>
CRITICAL_SECTION *AsCriticalSection(T* opaque_buffer) {
  static_assert(sizeof(T) >= sizeof(CRITICAL_SECTION),
                "The opaque buffer must have sufficient space to store a "
                "CRITICAL_SECTION structure");
  return reinterpret_cast<CRITICAL_SECTION *>(opaque_buffer);
}

template <typename T>
SRWLOCK *AsSRWLock(T* opaque_buffer) {
  static_assert(sizeof(T) >= sizeof(SRWLOCK),
                "The opaque buffer must have sufficient space to store a "
                "SRWLOCK structure");
  return reinterpret_cast<SRWLOCK *>(opaque_buffer);
}

// SlimReaderWriterLock is available on Windows Vista and later.
class SlimReaderWriterLock {
 public:
  static bool IsAvailable() {
    CallOnce(&g_once_, InitializeInternal);
    return g_is_available_;
  }
  static void InitializeSRWLock(__out SRWLOCK* lock) {
    g_initialize_srw_lock_(lock);
  }
  static void AcquireSRWLockExclusive(__inout SRWLOCK* lock) {
    g_acquire_srw_lock_exclusive_(lock);
  }
  static void AcquireSRWLockShared(__inout SRWLOCK* lock) {
    g_acquire_srw_lock_shared_(lock);
  }
  static void ReleaseSRWLockExclusive(__inout SRWLOCK* lock) {
    g_release_srw_lock_exclusive_(lock);
  }
  static void ReleaseSRWLockShared(__inout SRWLOCK* lock) {
    g_release_srw_lock_shared_(lock);
  }

 private:
  typedef void (WINAPI *FPInitializeSRWLock)(__out SRWLOCK*);
  typedef void (WINAPI *FPAcquireSRWLockExclusive)(__inout SRWLOCK*);
  typedef void (WINAPI *FPAcquireSRWLockShared)(__inout SRWLOCK*);
  typedef void (WINAPI *FPReleaseSRWLockExclusive)(__inout SRWLOCK*);
  typedef void (WINAPI *FPReleaseSRWLockShared)(__inout SRWLOCK*);

  static void InitializeInternal() {
    g_is_available_ = false;
    const HMODULE module = WinUtil::GetSystemModuleHandle(L"kernel32.dll");
    if (module == NULL) {
      return;
    }
    g_initialize_srw_lock_ = reinterpret_cast<FPInitializeSRWLock>(
        ::GetProcAddress(module, "InitializeSRWLock"));
    if (g_initialize_srw_lock_ == NULL) {
      return;
    }
    g_acquire_srw_lock_exclusive_ =
        reinterpret_cast<FPAcquireSRWLockExclusive>(
            ::GetProcAddress(module, "AcquireSRWLockExclusive"));
    if (g_acquire_srw_lock_exclusive_ == NULL) {
      return;
    }
    g_acquire_srw_lock_shared_ = reinterpret_cast<FPAcquireSRWLockShared>(
        ::GetProcAddress(module, "AcquireSRWLockShared"));
    if (g_acquire_srw_lock_shared_ == NULL) {
      return;
    }
    g_release_srw_lock_exclusive_ =
        reinterpret_cast<FPReleaseSRWLockExclusive>(
            ::GetProcAddress(module, "ReleaseSRWLockExclusive"));
    if (g_release_srw_lock_exclusive_ == NULL) {
      return;
    }
    g_release_srw_lock_shared_ = reinterpret_cast<FPReleaseSRWLockShared>(
        ::GetProcAddress(module, "ReleaseSRWLockShared"));
    if (g_release_srw_lock_shared_ == NULL) {
      return;
    }
    g_is_available_ = true;
  }

  static once_t g_once_;
  static bool g_is_available_;
  static FPInitializeSRWLock g_initialize_srw_lock_;
  static FPAcquireSRWLockExclusive g_acquire_srw_lock_exclusive_;
  static FPAcquireSRWLockShared g_acquire_srw_lock_shared_;
  static FPReleaseSRWLockExclusive g_release_srw_lock_exclusive_;
  static FPReleaseSRWLockShared g_release_srw_lock_shared_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(SlimReaderWriterLock);
};

once_t SlimReaderWriterLock::g_once_ = MOZC_ONCE_INIT;
bool SlimReaderWriterLock::g_is_available_ = false;
SlimReaderWriterLock::FPInitializeSRWLock
    SlimReaderWriterLock::g_initialize_srw_lock_ = NULL;
SlimReaderWriterLock::FPAcquireSRWLockExclusive
    SlimReaderWriterLock::g_acquire_srw_lock_exclusive_  = NULL;
SlimReaderWriterLock::FPAcquireSRWLockShared
    SlimReaderWriterLock::g_acquire_srw_lock_shared_  = NULL;
SlimReaderWriterLock::FPReleaseSRWLockExclusive
    SlimReaderWriterLock::g_release_srw_lock_exclusive_  = NULL;
SlimReaderWriterLock::FPReleaseSRWLockShared
    SlimReaderWriterLock::g_release_srw_lock_shared_  = NULL;

}  // namespace

Mutex::Mutex() {
  ::InitializeCriticalSection(AsCriticalSection(&opaque_buffer_));
}

Mutex::~Mutex() {
  ::DeleteCriticalSection(AsCriticalSection(&opaque_buffer_));
}

void Mutex::Lock() {
  ::EnterCriticalSection(AsCriticalSection(&opaque_buffer_));
}

bool Mutex::TryLock() {
  return ::TryEnterCriticalSection(AsCriticalSection(&opaque_buffer_)) != FALSE;
}

void Mutex::Unlock() {
  ::LeaveCriticalSection(AsCriticalSection(&opaque_buffer_));
}

ReaderWriterMutex::ReaderWriterMutex() {
  if (MultipleReadersThreadsSupported()) {
    SlimReaderWriterLock::InitializeSRWLock(AsSRWLock(&opaque_buffer_));
  } else {
    ::InitializeCriticalSection(AsCriticalSection(&opaque_buffer_));
  }
}

ReaderWriterMutex::~ReaderWriterMutex() {
  if (!MultipleReadersThreadsSupported()) {
    ::DeleteCriticalSection(AsCriticalSection(&opaque_buffer_));
  }
}

void ReaderWriterMutex::ReaderLock() {
  if (MultipleReadersThreadsSupported()) {
    SlimReaderWriterLock::AcquireSRWLockShared(AsSRWLock(&opaque_buffer_));
  } else {
    ::EnterCriticalSection(AsCriticalSection(&opaque_buffer_));
  }
}

void ReaderWriterMutex::WriterLock() {
  if (MultipleReadersThreadsSupported()) {
    SlimReaderWriterLock::AcquireSRWLockExclusive(AsSRWLock(&opaque_buffer_));
  } else {
    ::EnterCriticalSection(AsCriticalSection(&opaque_buffer_));
  }
}

void ReaderWriterMutex::ReaderUnlock() {
  if (MultipleReadersThreadsSupported()) {
    SlimReaderWriterLock::ReleaseSRWLockShared(AsSRWLock(&opaque_buffer_));
  } else {
    ::LeaveCriticalSection(AsCriticalSection(&opaque_buffer_));
  }
}

void ReaderWriterMutex::WriterUnlock() {
  if (MultipleReadersThreadsSupported()) {
    SlimReaderWriterLock::ReleaseSRWLockExclusive(AsSRWLock(&opaque_buffer_));
  } else {
    ::LeaveCriticalSection(AsCriticalSection(&opaque_buffer_));
  }
}

bool ReaderWriterMutex::MultipleReadersThreadsSupported() {
  return SlimReaderWriterLock::IsAvailable();
}

#else  // Hereafter, we have pthread-based implementation

namespace {

template <typename T>
pthread_mutex_t *AsPthreadMutexT(T* opaque_buffer) {
  static_assert(sizeof(T) >= sizeof(pthread_mutex_t),
                "The opaque buffer must have sufficient space to store a "
                "pthread_mutex_t structure");
  return reinterpret_cast<pthread_mutex_t *>(opaque_buffer);
}

}  // namespace

Mutex::Mutex() {
  // make RECURSIVE lock:
  // The default is no-recursive lock.
  // When mutex.Lock() is called while the mutex is already locked,
  // mutex will be blocked. This behavior is not compatible with windows.
  // We set PTHREAD_MUTEX_RECURSIVE_NP to make the mutex recursive-lock

  // PTHREAD_MUTEX_RECURSIVE_NP and PTHREAD_MUTEX_RECURSIVE seem to be
  // variants.  For example, Mac OS X 10.4 had
  // PTHREAD_MUTEX_RECURSIVE_NP but Mac OS X 10.5 does not
  pthread_mutexattr_t attr;
  pthread_mutexattr_init(&attr);
#if defined(OS_MACOSX)
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#elif defined(OS_LINUX)
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
#else
#error "This platform is not supported."
#endif
  pthread_mutex_init(AsPthreadMutexT(&opaque_buffer_), &attr);
}

Mutex::~Mutex() {
  pthread_mutex_destroy(AsPthreadMutexT(&opaque_buffer_));
}

void Mutex::Lock() {
  pthread_mutex_lock(AsPthreadMutexT(&opaque_buffer_));
}

bool Mutex::TryLock() {
  return pthread_mutex_trylock(AsPthreadMutexT(&opaque_buffer_)) == 0;
}

void Mutex::Unlock() {
  pthread_mutex_unlock(AsPthreadMutexT(&opaque_buffer_));
}

#ifdef MOZC_USE_PEPPER_FILE_IO
pthread_mutex_t *Mutex::raw_mutex() {
  return AsPthreadMutexT(&opaque_buffer_);
}
#endif  // MOZC_USE_PEPPER_FILE_IO

#ifdef MOZC_PTHREAD_HAS_READER_WRITER_LOCK
// Use pthread native reader writer lock.
namespace {

template <typename T>
pthread_rwlock_t *AsPthreadRWLockT(T* opaque_buffer) {
  static_assert(sizeof(T) >= sizeof(pthread_rwlock_t),
                "The opaque buffer must have sufficient space to store a "
                "pthread_rwlock_t structure");
  return reinterpret_cast<pthread_rwlock_t *>(opaque_buffer);
}

}  // namespace

ReaderWriterMutex::ReaderWriterMutex() {
  pthread_rwlock_init(AsPthreadRWLockT(&opaque_buffer_), NULL);
}

ReaderWriterMutex::~ReaderWriterMutex() {
  pthread_rwlock_destroy(AsPthreadRWLockT(&opaque_buffer_));
}

void ReaderWriterMutex::ReaderLock() {
  pthread_rwlock_rdlock(AsPthreadRWLockT(&opaque_buffer_));
}

void ReaderWriterMutex::ReaderUnlock() {
  pthread_rwlock_unlock(AsPthreadRWLockT(&opaque_buffer_));
}

void ReaderWriterMutex::WriterLock() {
  pthread_rwlock_wrlock(AsPthreadRWLockT(&opaque_buffer_));
}

void ReaderWriterMutex::WriterUnlock() {
  pthread_rwlock_unlock(AsPthreadRWLockT(&opaque_buffer_));
}

bool ReaderWriterMutex::MultipleReadersThreadsSupported() {
  return true;
}

#else

// Fallback implementations as ReaderWriterLock is not available.
ReaderWriterMutex::ReaderWriterMutex() {
  // Non-recursive lock is OK.
  pthread_mutex_init(AsPthreadMutexT(&opaque_buffer_), NULL);
}

ReaderWriterMutex::~ReaderWriterMutex() {
  pthread_mutex_destroy(AsPthreadMutexT(&opaque_buffer_));
}

void ReaderWriterMutex::ReaderLock() {
  pthread_mutex_lock(AsPthreadMutexT(&opaque_buffer_));
}

void ReaderWriterMutex::WriterLock() {
  pthread_mutex_lock(AsPthreadMutexT(&opaque_buffer_));
}

void ReaderWriterMutex::ReaderUnlock() {
  pthread_mutex_unlock(AsPthreadMutexT(&opaque_buffer_));
}

void ReaderWriterMutex::WriterUnlock() {
  pthread_mutex_unlock(AsPthreadMutexT(&opaque_buffer_));
}

bool ReaderWriterMutex::MultipleReadersThreadsSupported() {
  return false;
}

#endif  // MOZC_PTHREAD_HAS_READER_WRITER_LOCK

#endif  // OS_WIN or pthread

void CallOnce(once_t *once, void (*func)()) {
  if (once == NULL || func == NULL) {
    return;
  }

  if (once->state != ONCE_INIT) {
    return;
  }

  // change the counter in atomic
  if (0 == InterlockedCompareExchange(&(once->counter), 1, 0)) {
    // call func
    (*func)();
    // change the status to be ONCE_DONE in atomic
    // Maybe we won't use it, but in order to make memory barrier,
    // we use InterlockedCompareExchange just in case.
    InterlockedCompareExchange(&(once->state), ONCE_DONE, ONCE_INIT);
  } else {
    while (once->state == ONCE_INIT) {
#ifdef OS_WIN
      ::YieldProcessor();
#endif  // OS_WIN
    }  // busy loop
  }
}

void ResetOnce(once_t *once) {
  InterlockedCompareExchange(&(once->state), ONCE_INIT, ONCE_DONE);
  InterlockedCompareExchange(&(once->counter), 0, 1);
}

}  // namespace mozc
