//===-- llvm/Support/thread.h - Wrapper for <thread> ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This header is a wrapper for <thread> that works around problems with the
// MSVC headers when exceptions are disabled. It also provides llvm::thread,
// which is either a typedef of std::thread or a replacement that calls the
// function synchronously depending on the value of LLVM_ENABLE_THREADS.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_THREAD_H
#define LLVM_SUPPORT_THREAD_H

#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"

#ifdef _WIN32
typedef unsigned long DWORD;
typedef void *PVOID;
typedef PVOID HANDLE;
#endif

#if LLVM_ENABLE_THREADS

#include <thread>

namespace llvm {

#if LLVM_ON_UNIX || _WIN32

/// LLVM thread following std::thread interface with added constructor to
/// specify stack size.
class thread {
  template <typename FPtr, typename... Args, size_t... Indices>
  static void Apply(std::tuple<FPtr, Args...> &Callee,
                    std::index_sequence<Indices...>) {
    std::move(std::get<0>(Callee))(std::move(std::get<Indices + 1>(Callee))...);
  }

  template <typename CalleeTuple> static void GenericThreadProxy(void *Ptr) {
    std::unique_ptr<CalleeTuple> Callee(static_cast<CalleeTuple *>(Ptr));

    // FIXME: use std::apply when C++17 is allowed.
    std::make_index_sequence<std::tuple_size<CalleeTuple>() - 1> Indices{};
    Apply(*Callee.get(), Indices);
  }

public:
#if LLVM_ON_UNIX
  using native_handle_type = pthread_t;
  using id = pthread_t;
  using start_routine_type = void *(*)(void *);

  template <typename CalleeTuple> static void *ThreadProxy(void *Ptr) {
    GenericThreadProxy<CalleeTuple>(Ptr);
    return nullptr;
  }
#elif _WIN32
  using native_handle_type = HANDLE;
  using id = DWORD;
  using start_routine_type = unsigned(__stdcall *)(void *);

  template <typename CalleeTuple>
  static unsigned __stdcall ThreadProxy(void *Ptr) {
    GenericThreadProxy<CalleeTuple>(Ptr);
    return 0;
  }
#endif

  static const llvm::Optional<unsigned> DefaultStackSize;

  thread() : Thread(native_handle_type()) {}
  thread(thread &&Other) noexcept
      : Thread(std::exchange(Other.Thread, native_handle_type())) {}

  template <class Function, class... Args>
  explicit thread(Function &&f, Args &&...args)
      : thread(DefaultStackSize, f, args...) {}

  template <class Function, class... Args>
  explicit thread(llvm::Optional<unsigned> StackSizeInBytes, Function &&f,
                  Args &&...args);
  thread(const thread &) = delete;

  ~thread() {
    if (joinable())
      std::terminate();
  }

  thread &operator=(thread &&Other) noexcept {
    if (joinable())
      std::terminate();
    Thread = std::exchange(Other.Thread, native_handle_type());
    return *this;
  }

  bool joinable() const noexcept { return Thread != native_handle_type(); }

  inline id get_id() const noexcept;

  native_handle_type native_handle() const noexcept { return Thread; }

  static unsigned hardware_concurrency() {
    return std::thread::hardware_concurrency();
  };

  inline void join();
  inline void detach();

  void swap(llvm::thread &Other) noexcept { std::swap(Thread, Other.Thread); }

private:
  native_handle_type Thread;
};

thread::native_handle_type
llvm_execute_on_thread_impl(thread::start_routine_type ThreadFunc, void *Arg,
                            llvm::Optional<unsigned> StackSizeInBytes);
void llvm_thread_join_impl(thread::native_handle_type Thread);
void llvm_thread_detach_impl(thread::native_handle_type Thread);
thread::id llvm_thread_get_id_impl(thread::native_handle_type Thread);
thread::id llvm_thread_get_current_id_impl();

template <class Function, class... Args>
thread::thread(llvm::Optional<unsigned> StackSizeInBytes, Function &&f,
               Args &&...args) {
  typedef std::tuple<std::decay_t<Function>, std::decay_t<Args>...> CalleeTuple;
  std::unique_ptr<CalleeTuple> Callee(
      new CalleeTuple(std::forward<Function>(f), std::forward<Args>(args)...));

  Thread = llvm_execute_on_thread_impl(ThreadProxy<CalleeTuple>, Callee.get(),
                                       StackSizeInBytes);
  if (Thread != native_handle_type())
    Callee.release();
}

thread::id thread::get_id() const noexcept {
  return llvm_thread_get_id_impl(Thread);
}

void thread::join() {
  llvm_thread_join_impl(Thread);
  Thread = native_handle_type();
}

void thread::detach() {
  llvm_thread_detach_impl(Thread);
  Thread = native_handle_type();
}

namespace this_thread {
inline thread::id get_id() { return llvm_thread_get_current_id_impl(); }
} // namespace this_thread

#else // !LLVM_ON_UNIX && !_WIN32

/// std::thread backed implementation of llvm::thread interface that ignores the
/// stack size request.
class thread {
public:
  using native_handle_type = std::thread::native_handle_type;
  using id = std::thread::id;

  thread() : Thread(std::thread()) {}
  thread(thread &&Other) noexcept
      : Thread(std::exchange(Other.Thread, std::thread())) {}

  template <class Function, class... Args>
  explicit thread(llvm::Optional<unsigned> StackSizeInBytes, Function &&f,
                  Args &&...args)
      : Thread(std::forward<Function>(f), std::forward<Args>(args)...) {}

  template <class Function, class... Args>
  explicit thread(Function &&f, Args &&...args) : Thread(f, args...) {}

  thread(const thread &) = delete;

  ~thread() {}

  thread &operator=(thread &&Other) noexcept {
    Thread = std::exchange(Other.Thread, std::thread());
    return *this;
  }

  bool joinable() const noexcept { return Thread.joinable(); }

  id get_id() const noexcept { return Thread.get_id(); }

  native_handle_type native_handle() noexcept { return Thread.native_handle(); }

  static unsigned hardware_concurrency() {
    return std::thread::hardware_concurrency();
  };

  inline void join() { Thread.join(); }
  inline void detach() { Thread.detach(); }

  void swap(llvm::thread &Other) noexcept { std::swap(Thread, Other.Thread); }

private:
  std::thread Thread;
};

namespace this_thread {
  inline thread::id get_id() { return std::this_thread::get_id(); }
}

#endif // LLVM_ON_UNIX || _WIN32

} // namespace llvm

#else // !LLVM_ENABLE_THREADS

#include <utility>

namespace llvm {

struct thread {
  thread() {}
  thread(thread &&other) {}
  template <class Function, class... Args>
  explicit thread(llvm::Optional<unsigned> StackSizeInBytes, Function &&f,
                  Args &&...args) {
    f(std::forward<Args>(args)...);
  }
  template <class Function, class... Args>
  explicit thread(Function &&f, Args &&...args) {
    f(std::forward<Args>(args)...);
  }
  thread(const thread &) = delete;

  void detach() {
    report_fatal_error("Detaching from a thread does not make sense with no "
                       "threading support");
  }
  void join() {}
  static unsigned hardware_concurrency() { return 1; };
};

} // namespace llvm

#endif // LLVM_ENABLE_THREADS

#endif // LLVM_SUPPORT_THREAD_H
