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