/*
 * 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"

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

namespace art {

static inline void CheckSafeToLockOrUnlock(MutexRank rank, bool is_locking) {
#ifndef NDEBUG
  if (rank == -1) {
    return;
  }
  Thread* self = Thread::Current();
  if (self != NULL) {
    self->CheckSafeToLockOrUnlock(rank, is_locking);
  }
#endif
}

static inline void CheckSafeToWait(MutexRank rank) {
#ifndef NDEBUG
  Thread* self = Thread::Current();
  if (self != NULL) {
    self->CheckSafeToWait(rank);
  }
#endif
}

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;
    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_));
}

pid_t Mutex::GetOwner() {
#if defined(__BIONIC__)
  return static_cast<pid_t>((mutex_.value >> 16) & 0xffff);
#elif defined(__GLIBC__)
  struct __attribute__((__may_alias__)) glibc_pthread_t {
    int lock;
    unsigned int count;
    int owner;
    // ...other stuff we don't care about.
  };
  return reinterpret_cast<glibc_pthread_t*>(&mutex_)->owner;
#elif defined(__APPLE__)
  // We don't know a way to implement this for Mac OS.
  return 0;
#else
  UNIMPLEMENTED(FATAL);
  return 0;
#endif
}

uint32_t Mutex::GetDepth() {
  bool held = (GetOwner() == GetTid());
  if (!held) {
    return 0;
  }
  uint32_t depth;
#if defined(__BIONIC__)
  depth = static_cast<uint32_t>((mutex_.value >> 2) & 0x7ff) + 1;
#elif defined(__GLIBC__)
  struct __attribute__((__may_alias__)) glibc_pthread_t {
    int lock;
    unsigned int count;
    int owner;
    // ...other stuff we don't care about.
  };
  depth = reinterpret_cast<glibc_pthread_t*>(&mutex_)->count;
#elif defined(__APPLE__)
  // We don't know a way to implement this for Mac OS.
  return 0;
#else
  UNIMPLEMENTED(FATAL);
  return 0;
#endif
  CHECK_NE(0U, depth) << "owner=" << GetOwner() << " tid=" << GetTid();
  return depth;
}

pid_t Mutex::GetTid() {
  return ::art::GetTid();
}

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.GetRank());
  CHECK_MUTEX_CALL(pthread_cond_wait, (&cond_, mutex.GetImpl()));
}

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.GetRank());
  int rc = TIMEDWAIT(&cond_, mutex.GetImpl(), &ts);
  if (rc != 0 && rc != ETIMEDOUT) {
    errno = rc;
    PLOG(FATAL) << "TimedWait failed for " << name_;
  }
}

std::ostream& operator<<(std::ostream& os, const MutexRank& rhs) {
  switch (rhs) {
    case kHeapLock: os << "HeapLock"; break;
    case kThreadListLock: os << "ThreadListLock"; break;
    case kThreadSuspendCountLock: os << "ThreadSuspendCountLock"; break;
    default: os << "MutexRank[" << static_cast<int>(rhs) << "]"; break;
  }
  return os;
}

}  // namespace
