#ifndef _LIBCPP_EXTERNAL_PIN_THREADING_SUPPORT
#define _LIBCPP_EXTERNAL_PIN_THREADING_SUPPORT

#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS

_LIBCPP_BEGIN_NAMESPACE_STD

#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS

// Mutex
typedef int __libcpp_mutex_t;
#define _LIBCPP_MUTEX_INITIALIZER 0

typedef int __libcpp_recursive_mutex_t;

// Condition Variable
typedef void* __libcpp_condvar_t;
#define _LIBCPP_CONDVAR_INITIALIZER 0

// Execute once
typedef void* __libcpp_exec_once_flag;
#define _LIBCPP_EXEC_ONCE_INITIALIZER 0

typedef ::timespec __libcpp_timespec_t;

// Thread ID
typedef long __libcpp_thread_id;

// Thread
#define _LIBCPP_NULL_THREAD 0U

typedef void* __libcpp_thread_t;

// Thread Local Storage
typedef long __libcpp_tls_key;

#define _LIBCPP_TLS_DESTRUCTOR_CC

// Mutex
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);

_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);

_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);

_LIBCPP_THREAD_ABI_VISIBILITY
__libcpp_thread_id __libcpp_thread_get_current_id();

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY
void __libcpp_thread_yield();

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_mutex_lock(__libcpp_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);

// Thread local storage
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_tls_create(__libcpp_tls_key* __key,
                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));

_LIBCPP_THREAD_ABI_VISIBILITY
void *__libcpp_tls_get(__libcpp_tls_key __key);

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);

// Thread
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);

_LIBCPP_THREAD_ABI_VISIBILITY
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
                           void *__arg);

// Condition variable
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);

_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);

_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
                               __libcpp_timespec_t *__ts);

#if 1
# define warning_dump()
# define implement_dump()
#else
# define warning_dump(_fname) {printf("==> not implemeted call to %s\n", _fname);fflush(stdout);}
# define implement_dump(_fname) {printf("==> not implemented call to %s\n", _fname);fflush(stdout);}
#endif

// Mutex
_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
{
    warning_dump();
    return -1;
}
 
_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
{
    warning_dump();
    return false;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
{
    warning_dump();
    return -1;
}
 
_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
{
    implement_dump();
    return 0;
}
 
_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
{
    warning_dump();
    return false;
}
 
_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
{
    implement_dump();
    return 0;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
{
    implement_dump();
    return 0;
}

// Condition variable

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
{
    warning_dump();
    return -1;
}
 
_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
{
    warning_dump();
    return -1;
}
 
_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
                               timespec *__ts)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
{
    warning_dump();
    return -1;
}

// Execute once

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
                          void (*init_routine)(void))
{
    warning_dump();
    return -1;
}

// Thread id

_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
    warning_dump();
    return false;
}

_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
    warning_dump();
    return false;
}

// Thread

_LIBCPP_HIDE_FROM_ABI inline
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t)
{
    warning_dump();
    return false;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
                           void *__arg)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
__libcpp_thread_id __libcpp_thread_get_current_id()
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_join(__libcpp_thread_t *__t)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_thread_detach(__libcpp_thread_t *__t)
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
void __libcpp_thread_yield()
{
    warning_dump();
}

_LIBCPP_HIDE_FROM_ABI inline
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
{
    warning_dump();
}

// Thread local storage

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_tls_create(__libcpp_tls_key* __key,
                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
{
    warning_dump();
    return -1;
}

_LIBCPP_HIDE_FROM_ABI inline
void *__libcpp_tls_get(__libcpp_tls_key __key)
{
    warning_dump();
    return NULL;
}

_LIBCPP_HIDE_FROM_ABI inline
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
{
    warning_dump();
    return -1;
}

_LIBCPP_END_NAMESPACE_STD

#endif //_LIBCPP_EXTERNAL_PIN_THREADING_SUPPORT
