#ifndef USR_PTHREAD_H #define USR_PTHREAD_H /* Includes */ #include #include /* Macros */ // internal macros #define _INITIALIZED_RWLOCK ( 1 << 17 ) // pthread-specified macros #define PTHREAD_CREATE_JOINABLE 0 #define PTHREAD_CREATE_DETACHED 1 #define PTHREAD_PRIO_INHERIT 0 /* TODO */ #define PTHREAD_PRIO_NONE 0 /* TODO */ #define PTHREAD_PRIO_PROTECT 0 /* TODO */ enum { PTHREAD_SCOPE_SYSTEM, #define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_PROCESS #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS }; enum { PTHREAD_INHERIT_SCHED, #define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED PTHREAD_EXPLICIT_SCHED #define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED }; /* Single UNIX Specification v. 2 and later */ #define PTHREAD_MUTEX_NORMAL 0 #define PTHREAD_MUTEX_RECURSIVE 1 #define PTHREAD_MUTEX_ERRORCHECK 2 #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL /* for compatibility (prior to SUS v.2) */ #define PTHREAD_MUTEX_TIMED_NP PTHREAD_MUTEX_NORMAL #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE #define PTHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK #define PTHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_NORMAL #define PTHREAD_MUTEX_ADAPTIVE_NP PTHREAD_MUTEX_FAST_NP #define PTHREAD_MUTEX_INITIALIZER { .__owner = NULL, .__bitflags = 0x1 } #define PTHREAD_COND_INITIALIZER { .__mutex = NULL, .__counter = 0 } #define PTHREAD_ONCE_INIT { .__mtx = { .__bitflags = 0x3 } } #define PTHREAD_DESTRUCTOR_ITERATIONS 8 #define PTHREAD_CANCELED ( (void *) -1 ) #define PTHREAD_CANCEL_ENABLE 0 #define PTHREAD_CANCEL_DISABLE 1 #define PTHREAD_CANCEL_DEFERRED 0 #define PTHREAD_CANCEL_ASYNCHRONOUS 1 #define PTHREAD_PROCESS_PRIVATE 0 #define PTHREAD_PROCESS_SHARED 1 #define PTHREAD_RWLOCK_INITIALIZER { .__wrowner = 0, .__processShared = 0, .__rlocks = NULL } #define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP PTHREAD_RWLOCK_INITIALIZER #define PTHREAD_BARRIER_SERIAL_THREAD _HOST_PTHREAD_BARRIER_SERIAL_THREAD #if __has_attribute( error ) && __has_attribute( warning ) #define _PTHREAD_UNSUPPORTED __attribute__(( error("this function is not yet implemented") )) #define _PTHREAD_NO_EFFECT __attribute__(( warning("this function currently has no effect") )) #else #define _PTHREAD_UNSUPPORTED #define _PTHREAD_NO_EFFECT #endif #define _PTHREAD_NOINLINE __attribute__(( noinline )) #if defined( __cplusplus ) && __cplusplus >= 201103L #define _PTHREAD_NOEXCEPT noexcept #else #define _PTHREAD_NOEXCEPT __attribute__((nothrow)) #endif /* Data types */ typedef int pthread_attr_t; /* Thread in DiOS is defined as a task. * All its data and metadata are stored in task local storage. * * For `pthread_t` the `__dios_tls` holds in `__data` attribute * the _PthreadTLS data. * * Thread metadata are stored in form of _PThread in the _PthreadTLS. * */ #if _HOST_pthread_t_size == 4 typedef uint32_t pthread_t; #elif _HOST_pthread_t_size == 8 typedef uint64_t pthread_t; #else #error Host pthread_t is neither 4 nor 8 bytes. #endif struct _PThread; /* Each mutex tracks its owner to detect if another thread wants to unlock it. * * Attribute __once is used to detect a single execution of a thread * subroutine (see pthread_once implementation). * * Attribute __type stores type of mutex{PTHREAD_MUTEX_INITIALIZER, * PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP} * * Attribute __lockCounter maintains number of thread owners of this mutex {0,1}. * */ typedef union { struct { __dios_task __owner; union { struct { unsigned short __once:1; unsigned short __type:2; unsigned int __lockCounter:28; // change _mutex_adjust_count if bitfield size changes }; int32_t __bitflags; }; }; uint8_t __padding[ _HOST_pthread_mutex_t_size ]; } pthread_mutex_t; typedef struct { unsigned __type; // just 2 bits needed } pthread_mutexattr_t; typedef pthread_mutex_t pthread_spinlock_t; typedef struct { pthread_mutex_t *__mutex; // waits on mutex unsigned short __counter; } pthread_cond_t; typedef int pthread_condattr_t; typedef struct { pthread_mutex_t __mtx; } pthread_once_t; typedef int pthread_key_t; typedef struct _ReadLock { struct _PThread *__owner; int __count; struct _ReadLock *__next; } _ReadLock; typedef struct { struct _PThread *__wrowner; _ReadLock* __rlocks; // not bitfield, struct is padded anyway char __processShared; } pthread_rwlock_t; typedef int pthread_rwlockattr_t; typedef struct { unsigned short __counter; unsigned short __nthreads; } pthread_barrier_t; typedef int pthread_barrierattr_t; #include /* sched_param */ #include /* pid_t */ /* Function prototypes */ __BEGIN_DECLS /* Implementation prototypes */ void __pthread_initialize() _PTHREAD_NOEXCEPT; void __pthread_finalize() _PTHREAD_NOEXCEPT; int __register_atfork( void( *prepare )( void ), void ( parent )( void ), void( *child )( void ), void * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_atfork( void (*)(void), void (*)(void), void(*)(void) ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_create( pthread_t *, const pthread_attr_t *, void *(*)(void *), void * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; _PDCLIB_noreturn void pthread_exit( void * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_join( pthread_t, void ** ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_detach( pthread_t thread ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_yield(void) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_attr_destroy( pthread_attr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_attr_init( pthread_attr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_attr_getdetachstate( const pthread_attr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_attr_getguardsize( const pthread_attr_t *, size_t *) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getinheritsched( const pthread_attr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getschedparam( const pthread_attr_t *, struct sched_param * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getschedpolicy( const pthread_attr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getscope( const pthread_attr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getstack( const pthread_attr_t *, void **, size_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getstackaddr( const pthread_attr_t *, void ** ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_getstacksize( const pthread_attr_t *, size_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setdetachstate( pthread_attr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_attr_setguardsize( pthread_attr_t *, size_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setinheritsched( pthread_attr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setschedparam( pthread_attr_t *, const struct sched_param * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setschedpolicy( pthread_attr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setscope( pthread_attr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setstack( pthread_attr_t *, void *, size_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setstackaddr( pthread_attr_t *, void * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_attr_setstacksize( pthread_attr_t *, size_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int pthread_getconcurrency( void ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_getcpuclockid( pthread_t, clockid_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_getschedparam( pthread_t, int *, struct sched_param * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_setconcurrency( int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_setschedparam( pthread_t, int, const struct sched_param * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_setschedprio( pthread_t, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; pthread_t pthread_self( void ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_equal( pthread_t, pthread_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutex_destroy( pthread_mutex_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutex_init( pthread_mutex_t *, const pthread_mutexattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutex_lock( pthread_mutex_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutex_trylock( pthread_mutex_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutex_unlock( pthread_mutex_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutex_getprioceiling( const pthread_mutex_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutex_setprioceiling( pthread_mutex_t *, int, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutex_timedlock( pthread_mutex_t *, const struct timespec * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutexattr_destroy( pthread_mutexattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutexattr_init( pthread_mutexattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutexattr_gettype( const pthread_mutexattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutexattr_getprioceiling( const pthread_mutexattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutexattr_getprotocol( const pthread_mutexattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutexattr_getpshared( const pthread_mutexattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutexattr_settype( pthread_mutexattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_mutexattr_setprioceiling( pthread_mutexattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutexattr_setprotocol( pthread_mutexattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_mutexattr_setpshared( pthread_mutexattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_spin_destroy( pthread_spinlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_spin_init( pthread_spinlock_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_spin_lock( pthread_spinlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_spin_trylock( pthread_spinlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_spin_unlock( pthread_spinlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_key_create( pthread_key_t *, void (*)(void *) ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_key_delete( pthread_key_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_setspecific( pthread_key_t, const void * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; void *pthread_getspecific( pthread_key_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_cond_destroy( pthread_cond_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_cond_init( pthread_cond_t *, const pthread_condattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_cond_signal( pthread_cond_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_cond_broadcast( pthread_cond_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_cond_wait( pthread_cond_t *, pthread_mutex_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_cond_timedwait( pthread_cond_t *, pthread_mutex_t *, const struct timespec * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_condattr_destroy( pthread_condattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int pthread_condattr_getclock( const pthread_condattr_t *, clockid_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_condattr_getpshared( const pthread_condattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_condattr_init( pthread_condattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int pthread_condattr_setclock( pthread_condattr_t *, clockid_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_condattr_setpshared( pthread_condattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_once( pthread_once_t *, void (*)(void) ) _PTHREAD_NOINLINE; int pthread_setcancelstate( int, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_setcanceltype( int, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int pthread_cancel( pthread_t ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; void pthread_testcancel( void ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; void pthread_cleanup_push( void (*)(void *), void * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; void pthread_cleanup_pop( int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_destroy( pthread_rwlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_init( pthread_rwlock_t *, const pthread_rwlockattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_rdlock( pthread_rwlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_wrlock( pthread_rwlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_tryrdlock( pthread_rwlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_trywrlock( pthread_rwlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlock_unlock( pthread_rwlock_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlockattr_destroy( pthread_rwlockattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlockattr_getpshared( const pthread_rwlockattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int pthread_rwlockattr_init( pthread_rwlockattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_rwlockattr_setpshared( pthread_rwlockattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int pthread_barrier_destroy( pthread_barrier_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_barrier_init( pthread_barrier_t *, const pthread_barrierattr_t *, unsigned ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_barrier_wait( pthread_barrier_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE; int pthread_barrierattr_destroy( pthread_barrierattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_barrierattr_getpshared( const pthread_barrierattr_t *, int * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_barrierattr_init( pthread_barrierattr_t * ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int pthread_barrierattr_setpshared( pthread_barrierattr_t *, int ) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_UNSUPPORTED; int sched_get_priority_max(int) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int sched_get_priority_min(int) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int sched_getparam(pid_t, struct sched_param *) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int sched_getscheduler(pid_t) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int sched_rr_get_interval(pid_t, struct timespec *) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int sched_setparam(pid_t, const struct sched_param *) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; int sched_setscheduler(pid_t, int, const struct sched_param *) _PTHREAD_NOEXCEPT _PTHREAD_NOINLINE _PTHREAD_NO_EFFECT; __END_DECLS #endif