// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_THREADING_SUPPORT
#define _LIBCPP_THREADING_SUPPORT

#include <__config>

#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
#pragma GCC system_header
#endif

#ifndef _LIBCPP_HAS_NO_THREADS

#if defined(_LIBCPP_THREAD_API_PTHREAD)
#include <pthread.h>
#include <sched.h>
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#if defined(_LIBCPP_THREAD_API_PTHREAD)

// Mutex
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t __libcpp_mutex_t;

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
{
    pthread_mutexattr_t attr;
    int __ec = pthread_mutexattr_init(&attr);
    if (__ec) return __ec;
    __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    if (__ec)
    {
        pthread_mutexattr_destroy(&attr);
        return __ec;
    }
    __ec = pthread_mutex_init(__m, &attr);
    if (__ec)
    {
        pthread_mutexattr_destroy(&attr);
        return __ec;
    }
    __ec = pthread_mutexattr_destroy(&attr);
    if (__ec)
    {
        pthread_mutex_destroy(__m);
        return __ec;
    }
    return 0;
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
{
    return pthread_mutex_lock(__m);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
{
    return pthread_mutex_trylock(__m);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
{
    return pthread_mutex_unlock(__m);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
{
    return pthread_mutex_destroy(__m);
}

// Condition variable
#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
typedef pthread_cond_t __libcpp_condvar_t;

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
{
    return pthread_cond_signal(__cv);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
{
    return pthread_cond_broadcast(__cv);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
{
    return pthread_cond_wait(__cv, __m);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
{
    return pthread_cond_timedwait(__cv, __m, __ts);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
{
    return pthread_cond_destroy(__cv);
}

// Thread id
typedef pthread_t __libcpp_thread_id;

// Returns non-zero if the thread ids are equal, otherwise 0
inline _LIBCPP_ALWAYS_INLINE
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
    return pthread_equal(t1, t2) != 0;
}

// Returns non-zero if t1 < t2, otherwise 0
inline _LIBCPP_ALWAYS_INLINE
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
    return t1 < t2;
}

// Thread
typedef pthread_t __libcpp_thread_t;

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
{
    return pthread_create(__t, 0, __func, __arg);
}

inline _LIBCPP_ALWAYS_INLINE
__libcpp_thread_id __libcpp_thread_get_current_id()
{
    return pthread_self();
}

inline _LIBCPP_ALWAYS_INLINE
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
{
    return *__t;
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_thread_join(__libcpp_thread_t* __t)
{
    return pthread_join(*__t, 0);
}

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_thread_detach(__libcpp_thread_t* __t)
{
    return pthread_detach(*__t);
}

inline _LIBCPP_ALWAYS_INLINE
void __libcpp_thread_yield()
{
    sched_yield();
}

// Thread local storage
typedef pthread_key_t __libcpp_tl_key;

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*))
{
    return pthread_key_create(__key, __at_exit);
}

inline _LIBCPP_ALWAYS_INLINE
void* __libcpp_tl_get(__libcpp_tl_key __key)
{
    return pthread_getspecific(__key);
}

inline _LIBCPP_ALWAYS_INLINE
void __libcpp_tl_set(__libcpp_tl_key __key, void* __p)
{
    pthread_setspecific(__key, __p);
}

#else // !_LIBCPP_THREAD_API_PTHREAD
  #error "No thread API selected."
#endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_NO_THREADS

#endif // _LIBCPP_THREADING_SUPPORT
