// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(DART_HOST_OS_MACOS)

#include <assert.h>            // NOLINT
#include <errno.h>             // NOLINT
#include <mach/kern_return.h>  // NOLINT
#include <mach/mach.h>         // NOLINT
#include <mach/thread_act.h>   // NOLINT
#include <stdbool.h>           // NOLINT
#include <sys/sysctl.h>        // NOLINT
#include <sys/types.h>         // NOLINT
#include <unistd.h>            // NOLINT

#include "vm/flags.h"
#include "vm/os.h"
#include "vm/profiler.h"
#include "vm/signal_handler.h"
#include "vm/thread_interrupter.h"

namespace dart {

#if defined(DART_INCLUDE_PROFILER)

DECLARE_FLAG(bool, trace_thread_interrupter);

#if defined(HOST_ARCH_X64)
#define THREAD_STATE_FLAVOR x86_THREAD_STATE64
#define THREAD_STATE_FLAVOR_SIZE x86_THREAD_STATE64_COUNT
typedef x86_thread_state64_t thread_state_flavor_t;
#elif defined(HOST_ARCH_ARM64)
#define THREAD_STATE_FLAVOR ARM_THREAD_STATE64
#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE64_COUNT
typedef arm_thread_state64_t thread_state_flavor_t;
#elif defined(HOST_ARCH_ARM)
#define THREAD_STATE_FLAVOR ARM_THREAD_STATE32
#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE32_COUNT
typedef arm_thread_state32_t thread_state_flavor_t;
#else
#error "Unsupported architecture."
#endif  // HOST_ARCH_...

class ThreadInterrupterMacOS {
 public:
  explicit ThreadInterrupterMacOS(OSThread* os_thread) : os_thread_(os_thread) {
    ASSERT(os_thread != nullptr);
    mach_thread_ = pthread_mach_thread_np(os_thread->id());
    ASSERT(reinterpret_cast<void*>(mach_thread_) != nullptr);
#if !defined(DART_HOST_OS_WATCH)
    res = thread_suspend(mach_thread_);
#else
    res = KERN_FAILURE;
#endif
  }

  void CollectSample() {
    if (res != KERN_SUCCESS) {
      return;
    }
    auto count = static_cast<mach_msg_type_number_t>(THREAD_STATE_FLAVOR_SIZE);
    thread_state_flavor_t state;
#if !defined(DART_HOST_OS_WATCH)
    kern_return_t res =
        thread_get_state(mach_thread_, THREAD_STATE_FLAVOR,
                         reinterpret_cast<thread_state_t>(&state), &count);
#else
    USE(count);
    kern_return_t res = KERN_FAILURE;
#endif
    ASSERT(res == KERN_SUCCESS);
    Thread* thread = static_cast<Thread*>(os_thread_->thread_ignore_race());
    if (thread == nullptr) {
      return;
    }
    ThreadInterruptScope signal_handler_scope;
    // Mac profiling is cross-thread and TSAN doesn't know that thread_suspend
    // establishes synchronization. Also, the suspended thread might hold a
    // TSAN-internal lock for a location the sampling thread might read, which
    // would cause a deadlock.
    TsanIgnoreScope tsan_ignore_scope;
    Profiler::SampleThread(thread, ProcessState(state));
  }

  ~ThreadInterrupterMacOS() {
    if (res != KERN_SUCCESS) {
      return;
    }
#if !defined(DART_HOST_OS_WATCH)
    res = thread_resume(mach_thread_);
#else
    res = KERN_FAILURE;
#endif
    ASSERT(res == KERN_SUCCESS);
  }

 private:
  static InterruptedThreadState ProcessState(thread_state_flavor_t state) {
    InterruptedThreadState its;
#if defined(HOST_ARCH_X64)
    its.pc = state.__rip;
    its.fp = state.__rbp;
    its.csp = state.__rsp;
    its.dsp = state.__rsp;
    its.lr = 0;
#elif defined(HOST_ARCH_ARM64)
    its.pc = state.__pc;
    its.fp = state.__fp;
    its.csp = state.__sp;
    its.dsp = state.__sp;
    its.lr = state.__lr;
#elif defined(HOST_ARCH_ARM)
    its.pc = state.__pc;
    its.fp = state.__r[7];
    its.csp = state.__sp;
    its.dsp = state.__sp;
    its.lr = state.__lr;
#endif  // HOST_ARCH_...

#if defined(TARGET_ARCH_ARM64) && !defined(DART_INCLUDE_SIMULATOR)
    its.dsp = state.__x[SPREG];
#endif
    return its;
  }

  kern_return_t res;
  OSThread* os_thread_;
  mach_port_t mach_thread_;
};

void ThreadInterrupter::InterruptThread(OSThread* os_thread) {
  ASSERT(!OSThread::Compare(OSThread::GetCurrentThreadId(), os_thread->id()));
  if (FLAG_trace_thread_interrupter) {
    OS::PrintErr("ThreadInterrupter interrupting %p\n", os_thread->id());
  }

  ThreadInterrupterMacOS interrupter(os_thread);
  interrupter.CollectSample();
}

void ThreadInterrupter::InstallSignalHandler() {
  // Nothing to do on MacOS.
}

void ThreadInterrupter::RemoveSignalHandler() {
  // Nothing to do on MacOS.
}

#endif  // defined(DART_INCLUDE_PROFILER)

}  // namespace dart

#endif  // defined(DART_HOST_OS_MACOS)
