thread.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //===------------------------- thread.cpp----------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "__config"
  10. #ifndef _LIBCPP_HAS_NO_THREADS
  11. #include "thread"
  12. #include "exception"
  13. #include "vector"
  14. #include "future"
  15. #include "limits"
  16. #include <sys/types.h>
  17. #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  18. # include <sys/param.h>
  19. # if defined(BSD)
  20. # include <sys/sysctl.h>
  21. # endif // defined(BSD)
  22. #endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  23. #if !defined(_WIN32)
  24. # include <unistd.h>
  25. #endif // !_WIN32
  26. #if defined(__NetBSD__)
  27. #pragma weak pthread_create // Do not create libpthread dependency
  28. #endif
  29. #if defined(_WIN32)
  30. #include <windows.h>
  31. #endif
  32. _LIBCPP_BEGIN_NAMESPACE_STD
  33. thread::~thread()
  34. {
  35. if (__t_ != 0)
  36. terminate();
  37. }
  38. void
  39. thread::join()
  40. {
  41. int ec = EINVAL;
  42. if (__t_ != 0)
  43. {
  44. ec = __libcpp_thread_join(&__t_);
  45. if (ec == 0)
  46. __t_ = 0;
  47. }
  48. #ifndef _LIBCPP_NO_EXCEPTIONS
  49. if (ec)
  50. throw system_error(error_code(ec, system_category()), "thread::join failed");
  51. #endif // _LIBCPP_NO_EXCEPTIONS
  52. }
  53. void
  54. thread::detach()
  55. {
  56. int ec = EINVAL;
  57. if (__t_ != 0)
  58. {
  59. ec = __libcpp_thread_detach(&__t_);
  60. if (ec == 0)
  61. __t_ = 0;
  62. }
  63. #ifndef _LIBCPP_NO_EXCEPTIONS
  64. if (ec)
  65. throw system_error(error_code(ec, system_category()), "thread::detach failed");
  66. #endif // _LIBCPP_NO_EXCEPTIONS
  67. }
  68. unsigned
  69. thread::hardware_concurrency() _NOEXCEPT
  70. {
  71. #if defined(CTL_HW) && defined(HW_NCPU)
  72. unsigned n;
  73. int mib[2] = {CTL_HW, HW_NCPU};
  74. std::size_t s = sizeof(n);
  75. sysctl(mib, 2, &n, &s, 0, 0);
  76. return n;
  77. #elif defined(_SC_NPROCESSORS_ONLN)
  78. long result = sysconf(_SC_NPROCESSORS_ONLN);
  79. // sysconf returns -1 if the name is invalid, the option does not exist or
  80. // does not have a definite limit.
  81. // if sysconf returns some other negative number, we have no idea
  82. // what is going on. Default to something safe.
  83. if (result < 0)
  84. return 0;
  85. return static_cast<unsigned>(result);
  86. #elif defined(_WIN32)
  87. SYSTEM_INFO info;
  88. GetSystemInfo(&info);
  89. return info.dwNumberOfProcessors;
  90. #else // defined(CTL_HW) && defined(HW_NCPU)
  91. // TODO: grovel through /proc or check cpuid on x86 and similar
  92. // instructions on other architectures.
  93. # if defined(_MSC_VER) && ! defined(__clang__)
  94. _LIBCPP_WARNING("hardware_concurrency not yet implemented")
  95. # else
  96. # warning hardware_concurrency not yet implemented
  97. # endif
  98. return 0; // Means not computable [thread.thread.static]
  99. #endif // defined(CTL_HW) && defined(HW_NCPU)
  100. }
  101. namespace this_thread
  102. {
  103. void
  104. sleep_for(const chrono::nanoseconds& ns)
  105. {
  106. using namespace chrono;
  107. if (ns > nanoseconds::zero())
  108. {
  109. seconds s = duration_cast<seconds>(ns);
  110. timespec ts;
  111. typedef decltype(ts.tv_sec) ts_sec;
  112. _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();
  113. if (s.count() < ts_sec_max)
  114. {
  115. ts.tv_sec = static_cast<ts_sec>(s.count());
  116. ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count());
  117. }
  118. else
  119. {
  120. ts.tv_sec = ts_sec_max;
  121. ts.tv_nsec = giga::num - 1;
  122. }
  123. while (nanosleep(&ts, &ts) == -1 && errno == EINTR)
  124. ;
  125. }
  126. }
  127. } // this_thread
  128. __thread_specific_ptr<__thread_struct>&
  129. __thread_local_data()
  130. {
  131. static __thread_specific_ptr<__thread_struct> __p;
  132. return __p;
  133. }
  134. // __thread_struct_imp
  135. template <class T>
  136. class _LIBCPP_HIDDEN __hidden_allocator
  137. {
  138. public:
  139. typedef T value_type;
  140. T* allocate(size_t __n)
  141. {return static_cast<T*>(::operator new(__n * sizeof(T)));}
  142. void deallocate(T* __p, size_t) {::operator delete(static_cast<void*>(__p));}
  143. size_t max_size() const {return size_t(~0) / sizeof(T);}
  144. };
  145. class _LIBCPP_HIDDEN __thread_struct_imp
  146. {
  147. typedef vector<__assoc_sub_state*,
  148. __hidden_allocator<__assoc_sub_state*> > _AsyncStates;
  149. typedef vector<pair<condition_variable*, mutex*>,
  150. __hidden_allocator<pair<condition_variable*, mutex*> > > _Notify;
  151. _AsyncStates async_states_;
  152. _Notify notify_;
  153. __thread_struct_imp(const __thread_struct_imp&);
  154. __thread_struct_imp& operator=(const __thread_struct_imp&);
  155. public:
  156. __thread_struct_imp() {}
  157. ~__thread_struct_imp();
  158. void notify_all_at_thread_exit(condition_variable* cv, mutex* m);
  159. void __make_ready_at_thread_exit(__assoc_sub_state* __s);
  160. };
  161. __thread_struct_imp::~__thread_struct_imp()
  162. {
  163. for (_Notify::iterator i = notify_.begin(), e = notify_.end();
  164. i != e; ++i)
  165. {
  166. i->second->unlock();
  167. i->first->notify_all();
  168. }
  169. for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end();
  170. i != e; ++i)
  171. {
  172. (*i)->__make_ready();
  173. (*i)->__release_shared();
  174. }
  175. }
  176. void
  177. __thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m)
  178. {
  179. notify_.push_back(pair<condition_variable*, mutex*>(cv, m));
  180. }
  181. void
  182. __thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s)
  183. {
  184. async_states_.push_back(__s);
  185. __s->__add_shared();
  186. }
  187. // __thread_struct
  188. __thread_struct::__thread_struct()
  189. : __p_(new __thread_struct_imp)
  190. {
  191. }
  192. __thread_struct::~__thread_struct()
  193. {
  194. delete __p_;
  195. }
  196. void
  197. __thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m)
  198. {
  199. __p_->notify_all_at_thread_exit(cv, m);
  200. }
  201. void
  202. __thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s)
  203. {
  204. __p_->__make_ready_at_thread_exit(__s);
  205. }
  206. _LIBCPP_END_NAMESPACE_STD
  207. #endif // !_LIBCPP_HAS_NO_THREADS