//===------------------------- thread.cpp----------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include <__system_error/throw_system_error.h>
#include <__thread/poll_with_backoff.h>
#include <__thread/timed_backoff_policy.h>
#include <__utility/pair.h>
#include <exception>
#include <future>
#include <limits>
#include <thread>
#include <vector>

#if __has_include(<unistd.h>)
#  include <unistd.h> // for sysconf
#endif

#if defined(__NetBSD__)
#  pragma weak pthread_create // Do not create libpthread dependency
#endif

#ifdef _WIN32
#  include <windows.h>
#endif

#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
#  pragma comment(lib, "pthread")
#endif

_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS

thread::~thread() {
  if (!__libcpp_thread_isnull(&__t_))
    terminate();
}

void thread::join() {
  int ec = EINVAL;
  if (!__libcpp_thread_isnull(&__t_)) {
    ec = __libcpp_thread_join(&__t_);
    if (ec == 0)
      __t_ = _LIBCPP_NULL_THREAD;
  }

  if (ec)
    std::__throw_system_error(ec, "thread::join failed");
}

void thread::detach() {
  int ec = EINVAL;
  if (!__libcpp_thread_isnull(&__t_)) {
    ec = __libcpp_thread_detach(&__t_);
    if (ec == 0)
      __t_ = _LIBCPP_NULL_THREAD;
  }

  if (ec)
    std::__throw_system_error(ec, "thread::detach failed");
}

unsigned thread::hardware_concurrency() noexcept {
#if defined(_SC_NPROCESSORS_ONLN)
  long result = sysconf(_SC_NPROCESSORS_ONLN);
  // sysconf returns -1 if the name is invalid, the option does not exist or
  // does not have a definite limit.
  // if sysconf returns some other negative number, we have no idea
  // what is going on. Default to something safe.
  if (result < 0)
    return 0;
  return static_cast<unsigned>(result);
#elif defined(_WIN32)
  return static_cast<unsigned>(GetActiveProcessorCount(ALL_PROCESSOR_GROUPS));
#else // defined(CTL_HW) && defined(HW_NCPU)
  // TODO: grovel through /proc or check cpuid on x86 and similar
  // instructions on other architectures.
#  if defined(_LIBCPP_WARNING)
  _LIBCPP_WARNING("hardware_concurrency not yet implemented")
#  else
#    warning hardware_concurrency not yet implemented
#  endif
  return 0; // Means not computable [thread.thread.static]
#endif // defined(CTL_HW) && defined(HW_NCPU)
}

namespace this_thread {

void sleep_for(const chrono::nanoseconds& ns) {
  if (ns > chrono::nanoseconds::zero()) {
    __libcpp_thread_sleep_for(ns);
  }
}

} // namespace this_thread

__thread_specific_ptr<__thread_struct>& __thread_local_data() {
  // Even though __thread_specific_ptr's destructor doesn't actually destroy
  // anything (see comments there), we can't call it at all because threads may
  // outlive the static variable and calling its destructor means accessing an
  // object outside of its lifetime, which is UB.
  alignas(__thread_specific_ptr<__thread_struct>) static char __b[sizeof(__thread_specific_ptr<__thread_struct>)];
  static __thread_specific_ptr<__thread_struct>* __p = new (__b) __thread_specific_ptr<__thread_struct>();
  return *__p;
}

// __thread_struct_imp

template <class T>
class _LIBCPP_HIDDEN __hidden_allocator {
public:
  typedef T value_type;

  T* allocate(size_t __n) { return static_cast<T*>(::operator new(__n * sizeof(T))); }
  void deallocate(T* __p, size_t) { ::operator delete(static_cast<void*>(__p)); }

  size_t max_size() const { return size_t(~0) / sizeof(T); }
};

class _LIBCPP_HIDDEN __thread_struct_imp {
  typedef vector<__assoc_sub_state*, __hidden_allocator<__assoc_sub_state*> > _AsyncStates;
  typedef vector<pair<condition_variable*, mutex*>, __hidden_allocator<pair<condition_variable*, mutex*> > > _Notify;

  _AsyncStates async_states_;
  _Notify notify_;

  __thread_struct_imp(const __thread_struct_imp&);
  __thread_struct_imp& operator=(const __thread_struct_imp&);

public:
  __thread_struct_imp() {}
  ~__thread_struct_imp();

  void notify_all_at_thread_exit(condition_variable* cv, mutex* m);
  void __make_ready_at_thread_exit(__assoc_sub_state* __s);
};

__thread_struct_imp::~__thread_struct_imp() {
  for (_Notify::iterator i = notify_.begin(), e = notify_.end(); i != e; ++i) {
    i->first->notify_all();
    i->second->unlock();
  }
  for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); i != e; ++i) {
    (*i)->__make_ready();
    (*i)->__release_shared();
  }
}

void __thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m) {
  notify_.push_back(pair<condition_variable*, mutex*>(cv, m));
}

void __thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) {
  async_states_.push_back(__s);
  __s->__add_shared();
}

// __thread_struct

__thread_struct::__thread_struct() : __p_(new __thread_struct_imp) {}

__thread_struct::~__thread_struct() { delete __p_; }

void __thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m) {
  __p_->notify_all_at_thread_exit(cv, m);
}

void __thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) { __p_->__make_ready_at_thread_exit(__s); }

_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
_LIBCPP_END_NAMESPACE_STD
