#ifndef PTHREAD_HPP_INCLUDED
#define PTHREAD_HPP_INCLUDED

// Copyright (c) 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

#include <pthread.h>

#if defined( _POSIX_CXX09_EXTENSIONS )

typedef pthread_t pthread2_t;

inline pthread2_t __pthread_self()
{
    return pthread_self();
}

#else

struct pthread2_state;
typedef pthread2_state * pthread2_t;

int pthread_create( pthread2_t * thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg );
int pthread_detach( pthread2_t thread );
pthread2_t __pthread_self();
int pthread_cancel( pthread2_t thread );

inline bool pthread_equal( pthread2_t t1, pthread2_t t2 )
{
    return t1 == t2;
}

inline bool pthread_less_np( pthread2_t t1, pthread2_t t2 )
{
    return t1 < t2;
}

inline size_t pthread_hash_np( pthread2_t t1 )
{
    return (size_t)t1;
}

int pthread_attach_np( pthread2_t thread );

int pthread_once2_np( pthread_once_t * once_control, void (*init_routine)(void*), void * arg );

int pthread_join2_np( pthread2_t thread );
int pthread_tryjoin2_np( pthread2_t thread );
int pthread_timedjoin2_np( pthread2_t thread, const struct timespec * abstime );

int pthread_attr_copy_np( pthread_attr_t * target, pthread_attr_t const * source );
int pthread_mutexattr_copy_np( pthread_mutexattr_t * target, pthread_mutexattr_t const * source );
int pthread_condattr_copy_np( pthread_condattr_t * target, pthread_condattr_t const * source );
int pthread_rwlockattr_copy_np( pthread_rwlockattr_t * target, pthread_rwlockattr_t const * source );

#endif // !defined( _POSIX_CXX09_EXTENSIONS )

#ifdef PTW32_VERSION

#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1

typedef int clockid_t;

int clock_gettime( clockid_t clock_id, struct timespec * tp );
int nanosleep( const struct timespec * rqtp, struct timespec * rmtp );

int pthread_attr_getguardsize( const pthread_attr_t * attr, size_t * guardsize );
int pthread_attr_setguardsize( pthread_attr_t * attr, size_t guardsize );

inline int pthread_mutexattr_gettype( const pthread_mutexattr_t * attr, int * type )
{
    return pthread_mutexattr_gettype( const_cast< pthread_mutexattr_t * >( attr ), type );
}

int pthread_condattr_getclock( const pthread_condattr_t * attr, clockid_t * clock_id );
int pthread_condattr_setclock( pthread_condattr_t * attr, clockid_t clock_id );

#endif

#endif // #ifndef PTHREAD_HPP_INCLUDED
