//===------------------------- 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

#if defined(_LIBCPP_WIN32API)
#  include <windows.h>
#endif

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

_LIBCPP_BEGIN_NAMESPACE_STD

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(_LIBCPP_WIN32API)
  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_NAMESPACE_STD
