// -*- 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_HAS_THREAD_API_PTHREAD)
#include <pthread.h>
#include <sched.h>
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#if defined(_LIBCPP_HAS_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_HAS_THREAD_API_PTHREAD
  #error "No thread API selected."
#endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_NO_THREADS

#endif // _LIBCPP_THREADING_SUPPORT
