111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===------------------------- thread.cpp----------------------------------===// 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The LLVM Compiler Infrastructure 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is dual licensed under the MIT and the University of Illinois Open 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Source Licenses. See LICENSE.TXT for details. 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "__config" 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _LIBCPP_HAS_NO_THREADS 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "thread" 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "exception" 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vector" 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "future" 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "limits" 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <sys/types.h> 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <sys/param.h> 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# if defined(BSD) 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <sys/sysctl.h> 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif // defined(BSD) 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if !defined(_WIN32) 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <unistd.h> 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // !_WIN32 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__NetBSD__) 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#pragma weak pthread_create // Do not create libpthread dependency 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(_WIN32) 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <windows.h> 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_LIBCPP_BEGIN_NAMESPACE_STD 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertthread::~thread() 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__t_ != 0) 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert terminate(); 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertthread::join() 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int ec = __libcpp_thread_join(&__t_); 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _LIBCPP_NO_EXCEPTIONS 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (ec) 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert throw system_error(error_code(ec, system_category()), "thread::join failed"); 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (void)ec; 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _LIBCPP_NO_EXCEPTIONS 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __t_ = 0; 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertthread::detach() 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int ec = EINVAL; 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__t_ != 0) 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ec = __libcpp_thread_detach(&__t_); 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (ec == 0) 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __t_ = 0; 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _LIBCPP_NO_EXCEPTIONS 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (ec) 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert throw system_error(error_code(ec, system_category()), "thread::detach failed"); 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _LIBCPP_NO_EXCEPTIONS 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertunsigned 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertthread::hardware_concurrency() _NOEXCEPT 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(CTL_HW) && defined(HW_NCPU) 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unsigned n; 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int mib[2] = {CTL_HW, HW_NCPU}; 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::size_t s = sizeof(n); 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sysctl(mib, 2, &n, &s, 0, 0); 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return n; 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#elif defined(_SC_NPROCESSORS_ONLN) 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert long result = sysconf(_SC_NPROCESSORS_ONLN); 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // sysconf returns -1 if the name is invalid, the option does not exist or 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // does not have a definite limit. 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // if sysconf returns some other negative number, we have no idea 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // what is going on. Default to something safe. 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (result < 0) 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return 0; 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return static_cast<unsigned>(result); 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#elif defined(_WIN32) 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SYSTEM_INFO info; 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert GetSystemInfo(&info); 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return info.dwNumberOfProcessors; 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else // defined(CTL_HW) && defined(HW_NCPU) 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO: grovel through /proc or check cpuid on x86 and similar 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // instructions on other architectures. 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# if defined(_MSC_VER) && ! defined(__clang__) 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _LIBCPP_WARNING("hardware_concurrency not yet implemented") 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# else 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# warning hardware_concurrency not yet implemented 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return 0; // Means not computable [thread.thread.static] 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // defined(CTL_HW) && defined(HW_NCPU) 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace this_thread 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertsleep_for(const chrono::nanoseconds& ns) 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using namespace chrono; 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (ns > nanoseconds::zero()) 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert seconds s = duration_cast<seconds>(ns); 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert timespec ts; 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef decltype(ts.tv_sec) ts_sec; 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (s.count() < ts_sec_max) 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ts.tv_sec = static_cast<ts_sec>(s.count()); 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count()); 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ts.tv_sec = ts_sec_max; 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ts.tv_nsec = giga::num - 1; 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (nanosleep(&ts, &ts) == -1 && errno == EINTR) 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ; 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // this_thread 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_specific_ptr<__thread_struct>& 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_local_data() 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static __thread_specific_ptr<__thread_struct> __p; 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __p; 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// __thread_struct_imp 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T> 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _LIBCPP_HIDDEN __hidden_allocator 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef T value_type; 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert T* allocate(size_t __n) 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert {return static_cast<T*>(::operator new(__n * sizeof(T)));} 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void deallocate(T* __p, size_t) {::operator delete(static_cast<void*>(__p));} 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_t max_size() const {return size_t(~0) / sizeof(T);} 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass _LIBCPP_HIDDEN __thread_struct_imp 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef vector<__assoc_sub_state*, 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __hidden_allocator<__assoc_sub_state*> > _AsyncStates; 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef vector<pair<condition_variable*, mutex*>, 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __hidden_allocator<pair<condition_variable*, mutex*> > > _Notify; 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _AsyncStates async_states_; 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Notify notify_; 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __thread_struct_imp(const __thread_struct_imp&); 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __thread_struct_imp& operator=(const __thread_struct_imp&); 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __thread_struct_imp() {} 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__thread_struct_imp(); 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void notify_all_at_thread_exit(condition_variable* cv, mutex* m); 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void __make_ready_at_thread_exit(__assoc_sub_state* __s); 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct_imp::~__thread_struct_imp() 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (_Notify::iterator i = notify_.begin(), e = notify_.end(); 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i != e; ++i) 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i->second->unlock(); 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i->first->notify_all(); 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert i != e; ++i) 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (*i)->__make_ready(); 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (*i)->__release_shared(); 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m) 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert notify_.push_back(pair<condition_variable*, mutex*>(cv, m)); 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert async_states_.push_back(__s); 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __s->__add_shared(); 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// __thread_struct 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct::__thread_struct() 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : __p_(new __thread_struct_imp) 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct::~__thread_struct() 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert delete __p_; 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m) 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __p_->notify_all_at_thread_exit(cv, m); 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __p_->__make_ready_at_thread_exit(__s); 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_LIBCPP_END_NAMESPACE_STD 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // !_LIBCPP_HAS_NO_THREADS 238