/*
 * Copyright (C) 2011 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 "mutex.h"

#include <errno.h>

#include "logging.h"
#include "runtime.h"
#include "thread.h"
#include "utils.h"

#if defined(__APPLE__)
#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
#endif

#define CHECK_MUTEX_CALL(call, args) CHECK_PTHREAD_CALL(call, args, name_)

namespace art {

// This works on Mac OS 10.7, but hasn't been tested on older releases.
struct __attribute__((__may_alias__)) darwin_pthread_mutex_t {
  uint32_t padding0[2];
  uint32_t value;
  uint32_t padding1[5];
  uint64_t owner_tid;
  // ...other stuff we don't care about.
};

struct __attribute__((__may_alias__)) glibc_pthread_mutex_t {
  int lock;
  unsigned int count;
  int owner;
  // ...other stuff we don't care about.
};

static inline void CheckSafeToLockOrUnlock(MutexRank rank, bool is_locking) {
  if (!kIsDebugBuild) {
    return;
  }
  if (rank == -1) {
    return;
  }
  Thread::Current()->CheckSafeToLockOrUnlock(rank, is_locking);
}

static inline void CheckSafeToWait(MutexRank rank) {
  if (!kIsDebugBuild) {
    return;
  }
  Thread::Current()->CheckSafeToWait(rank);
}

Mutex::Mutex(const char* name, MutexRank rank) : name_(name), rank_(rank) {
  // Like Java, we use recursive mutexes.
  pthread_mutexattr_t attributes;
  CHECK_MUTEX_CALL(pthread_mutexattr_init, (&attributes));
  CHECK_MUTEX_CALL(pthread_mutexattr_settype, (&attributes, PTHREAD_MUTEX_RECURSIVE));
  CHECK_MUTEX_CALL(pthread_mutex_init, (&mutex_, &attributes));
  CHECK_MUTEX_CALL(pthread_mutexattr_destroy, (&attributes));
}

Mutex::~Mutex() {
  int rc = pthread_mutex_destroy(&mutex_);
  if (rc != 0) {
    errno = rc;
    // TODO: should we just not log at all if shutting down? this could be the logging mutex!
    bool shutting_down = Runtime::Current()->IsShuttingDown();
    PLOG(shutting_down ? WARNING : FATAL) << "pthread_mutex_destroy failed for " << name_;
  }
}

void Mutex::Lock() {
  CheckSafeToLockOrUnlock(rank_, true);
  CHECK_MUTEX_CALL(pthread_mutex_lock, (&mutex_));
  AssertHeld();
}

bool Mutex::TryLock() {
  int result = pthread_mutex_trylock(&mutex_);
  if (result == EBUSY) {
    return false;
  }
  if (result != 0) {
    errno = result;
    PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_;
  }
  CheckSafeToLockOrUnlock(rank_, true);
  AssertHeld();
  return true;
}

void Mutex::Unlock() {
  AssertHeld();
  CheckSafeToLockOrUnlock(rank_, false);
  CHECK_MUTEX_CALL(pthread_mutex_unlock, (&mutex_));
}

#if !defined(NDEBUG)
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED < 1060
// Mac OS 10.5 didn't have anything we could implement GetTid() with. One thing we could try would
// be using pthread_t instead of the actual tid; this would be acceptable in most places, and more
// portable. 10.5 is already obsolete, though, so doing so would probably be all pain for no gain.
void Mutex::AssertHeld() {}
void Mutex::AssertNotHeld() {}
#else
void Mutex::AssertHeld() {
  DCHECK_EQ(GetOwner(), static_cast<uint64_t>(GetTid()));
}

void Mutex::AssertNotHeld() {
  DCHECK_NE(GetOwner(), static_cast<uint64_t>(GetTid()));
}
#endif
#endif

uint64_t Mutex::GetOwner() {
#if defined(__BIONIC__)
  return static_cast<uint64_t>((mutex_.value >> 16) & 0xffff);
#elif defined(__GLIBC__)
  return reinterpret_cast<glibc_pthread_mutex_t*>(&mutex_)->owner;
#elif defined(__APPLE__)
  return reinterpret_cast<darwin_pthread_mutex_t*>(&mutex_)->owner_tid;
#else
#error unsupported C library
#endif
}

uint32_t Mutex::GetDepth() {
  bool held = (GetOwner() == static_cast<uint64_t>(GetTid()));
  if (!held) {
    return 0;
  }
  uint32_t depth;
#if defined(__BIONIC__)
  depth = static_cast<uint32_t>((mutex_.value >> 2) & 0x7ff) + 1;
#elif defined(__GLIBC__)
  depth = reinterpret_cast<glibc_pthread_mutex_t*>(&mutex_)->count;
#elif defined(__APPLE__)
  darwin_pthread_mutex_t* darwin_mutex = reinterpret_cast<darwin_pthread_mutex_t*>(&mutex_);
  depth = ((darwin_mutex->value >> 16) & 0xffff);
#else
#error unsupported C library
#endif
  CHECK_NE(depth, 0U) << "owner=" << GetOwner() << " tid=" << GetTid();
  return depth;
}

ConditionVariable::ConditionVariable(const std::string& name) : name_(name) {
  CHECK_MUTEX_CALL(pthread_cond_init, (&cond_, NULL));
}

ConditionVariable::~ConditionVariable() {
  CHECK_MUTEX_CALL(pthread_cond_destroy, (&cond_));
}

void ConditionVariable::Broadcast() {
  CHECK_MUTEX_CALL(pthread_cond_broadcast, (&cond_));
}

void ConditionVariable::Signal() {
  CHECK_MUTEX_CALL(pthread_cond_signal, (&cond_));
}

void ConditionVariable::Wait(Mutex& mutex) {
  CheckSafeToWait(mutex.rank_);
  CHECK_MUTEX_CALL(pthread_cond_wait, (&cond_, &mutex.mutex_));
}

void ConditionVariable::TimedWait(Mutex& mutex, const timespec& ts) {
#ifdef HAVE_TIMEDWAIT_MONOTONIC
#define TIMEDWAIT pthread_cond_timedwait_monotonic
#else
#define TIMEDWAIT pthread_cond_timedwait
#endif
  CheckSafeToWait(mutex.rank_);
  int rc = TIMEDWAIT(&cond_, &mutex.mutex_, &ts);
  if (rc != 0 && rc != ETIMEDOUT) {
    errno = rc;
    PLOG(FATAL) << "TimedWait failed for " << name_;
  }
}

}  // namespace
