// // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // pthread.cfa -- // // Author : Zhenyan Zhu // Created On : Sat Aug 6 16:29:18 2022 // Last Modified By : // Last Modified On : // Update Count : // #define __cforall_thread__ #define _GNU_SOURCE #include #include #include #include "locks.hfa" #include "bits/stack.hfa" #define check_nonnull(x) asm("": "+rm"(x)); if( x == 0p ) return EINVAL; /* pthread key, pthread once inner routine mutual exclusion */ static simple_owner_lock once_lock,key_lock,magic_mutex_check, concurrency_lock; //######################### Local Storage Helpers ######################### enum { PTHREAD_KEYS_MAX = 1024 }; struct pthread_values{ inline Seqable; void* value; bool in_use; }; static inline { pthread_values *& Back( pthread_values * n ) { return (pthread_values *)Back( (Seqable *)n ); } pthread_values *& Next( pthread_values * n ) { return (pthread_values *)Next( (Colable *)n ); } } struct pthread_keys { bool in_use; void (*destructor)( void * ); Sequence(pthread_values) threads; }; static void ?{}(pthread_keys& k){ k.threads{}; } // Create storage separately to ensure no constructors are called. static pthread_keys cfa_pthread_keys_storage[PTHREAD_KEYS_MAX] __attribute__((aligned (16))); static void init_pthread_storage(){ for (int i = 0; i < PTHREAD_KEYS_MAX; i++){ cfa_pthread_keys_storage[i]{}; } } #define cfa_pthread_keys ((pthread_keys *)cfa_pthread_keys_storage) /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 /* Number of iterations this implementation does. */ #define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS //######################### Parallelism Helpers ######################### struct Pthread_kernel_threads{ inline Colable; processor p; }; Pthread_kernel_threads *& Next( Pthread_kernel_threads * n ) { return (Pthread_kernel_threads *)Next( (Colable *)n ); } static Stack(Pthread_kernel_threads) cfa_pthreads_kernel_threads; static bool cfa_pthreads_kernel_threads_zero = false; // set to zero ? static int cfa_pthreads_no_kernel_threads = 1; // number of kernel threads //######################### Cond Helpers ######################### typedef pthread_cond_var(simple_owner_lock) cfa2pthr_cond_var_t; /* condvar helper routines */ static void init(pthread_cond_t* pcond){ static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); cfa2pthr_cond_var_t* _cond = (cfa2pthr_cond_var_t*)pcond; ?{}(*_cond); } static cfa2pthr_cond_var_t* get(pthread_cond_t* pcond){ static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); return (cfa2pthr_cond_var_t*)pcond; } static void destroy(pthread_cond_t* cond){ static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); ^?{}(*get(cond)); } //######################### Mutex Helper ######################### /* mutex helper routines */ static void mutex_check(pthread_mutex_t* t){ // Use double check to improve performance. // Check is safe on x86; volatile prevents compiler reordering volatile pthread_mutex_t *const mutex_ = t; // SKULLDUGGERY: not a portable way to access the kind field, /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h int _lock_val = ((pthread_mutex_t *)mutex_)->__data.__lock; // if pthread_mutex_t is initialized by PTHREAD_MUTEX_INITIALIZER, _lock_val should be 0 if ( _lock_val == 0 ) { lock(magic_mutex_check); _lock_val = ((pthread_mutex_t *)mutex_)->__data.__lock; if ( _lock_val == 0 ) { pthread_mutex_init( t, NULL ); } unlock(magic_mutex_check); } } // mutex_check static void init(pthread_mutex_t* plock){ static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); simple_owner_lock* _lock = (simple_owner_lock*)plock; ?{}(*_lock); } static simple_owner_lock* get(pthread_mutex_t* plock){ static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); return (simple_owner_lock*)plock; } static void destroy(pthread_mutex_t* plock){ static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); ^?{}(*get(plock)); } //######################### Attr helpers ######################### struct cfaPthread_attr_t { // thread attributes int contentionscope; int detachstate; size_t stacksize; void *stackaddr; int policy; int inheritsched; struct sched_param param; } typedef cfaPthread_attr_t; static const cfaPthread_attr_t default_attrs{ 0, 0, (size_t)65000, (void *)NULL, 0, 0, {0} }; static cfaPthread_attr_t* get(const pthread_attr_t* attr){ static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t),"sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)"); return (cfaPthread_attr_t*)attr; } //######################### Threads Helper ######################### // exception for cancel_stack in pthread_exit exception pthread_exit_exp {}; static vtable(pthread_exit_exp) exp_vt; thread cfaPthread{ cfaPthread_attr_t attr; pthread_t pthreadId; // pthreads return value void *joinval; // pthread attributes pthread_attr_t pthread_attr; void *(*start_routine)(void *); void *start_arg; // thread local data pthread_values* pthreadData; // flag used for tryjoin bool isTerminated; }; /* thread part routines */ // cfaPthread entry point void main(cfaPthread& _thread) with(_thread){ joinval = start_routine(start_arg); isTerminated = true; } static cfaPthread *lookup( pthread_t p ){ static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)"); return (cfaPthread*)p; } static void pthread_deletespecific_( pthread_values* values ) { // see uMachContext::invokeTask pthread_values* value; pthread_keys* key; bool destcalled = true; if (values != NULL){ for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) { destcalled = false; lock(key_lock); for (int i = 0; i < PTHREAD_KEYS_MAX; i++){ // for each valid key if ( values[i].in_use){ value = &values[i]; key = &cfa_pthread_keys[i]; value->in_use = false; remove(key->threads, *value); // if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with that key, // the value of the key is set to NULL, and then the function pointed to is called with the previously associated value as its sole argument. if (value->value != NULL && key->destructor != NULL){ unlock(key_lock); key->destructor(value->value); // run destructor lock(key_lock); destcalled = true; } // if value->value = NULL; } // if } // for unlock(key_lock); } // for free(values); } // if } static void ^?{}(cfaPthread & mutex t){ // delete pthread local storage pthread_values * values = t.pthreadData; pthread_deletespecific_(values); } static void ?{}(cfaPthread &t, pthread_t* _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) { static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread*)"); // set up user thread stackSize cfaPthread_attr_t * attr = get(_attr); ((thread&)t){ attr ? attr->stacksize: DEFAULT_STACK_SIZE }; // initialize _thread & cfaPthread id *_thread = t.pthreadId = (pthread_t)(&t); // if attr null, self attr will be set as default_attrs; else set to attr t.attr = (attr != NULL ? *attr : default_attrs); // init start routine and arguments t.start_routine = start_routine; t.start_arg = arg; t.pthreadData = NULL; } extern "C"{ //######################### Pthread Attrs ######################### int pthread_attr_init(pthread_attr_t *attr) libcfa_public __THROW { cfaPthread_attr_t* _attr = get(attr); ?{}(*_attr, default_attrs); return 0; } int pthread_attr_destroy(pthread_attr_t *attr) libcfa_public __THROW { ^?{}(*get(attr)); return 0; } int pthread_attr_setscope( pthread_attr_t *attr, int contentionscope ) libcfa_public __THROW { get( attr )->contentionscope = contentionscope; return 0; } // pthread_attr_setscope int pthread_attr_getscope( const pthread_attr_t *attr, int *contentionscope ) libcfa_public __THROW { *contentionscope = get( attr )->contentionscope; return 0; } // pthread_attr_getscope int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate ) libcfa_public __THROW { get( attr )->detachstate = detachstate; return 0; } // pthread_attr_setdetachstate int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ) libcfa_public __THROW { *detachstate = get( attr )->detachstate; return 0; } // pthread_attr_getdetachstate int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ) libcfa_public __THROW { get( attr )->stacksize = stacksize; return 0; } // pthread_attr_setstacksize int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ) libcfa_public __THROW { *stacksize = get( attr )->stacksize; return 0; } // pthread_attr_getstacksize int pthread_attr_getguardsize( const pthread_attr_t * /* attr */, size_t * /* guardsize */ ) libcfa_public __THROW { return 0; } // pthread_attr_getguardsize int pthread_attr_setguardsize( pthread_attr_t * /* attr */, size_t /* guardsize */ ) libcfa_public __THROW { return 0; } // pthread_attr_setguardsize int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ) libcfa_public __THROW { get( attr )->stackaddr = stackaddr; return 0; } // pthread_attr_setstackaddr int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ) libcfa_public __THROW { *stackaddr = get( attr )->stackaddr; return 0; } // pthread_attr_getstackaddr int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW { get( attr )->stackaddr = stackaddr; get( attr )->stacksize = stacksize; return 0; } // pthread_attr_setstack int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize ) libcfa_public __THROW { *stackaddr = get( attr )->stackaddr; *stacksize = get( attr )->stacksize; return 0; } // pthread_attr_getstack // Initialize thread attribute *attr with attributes corresponding to the // already running thread threadID. It shall be called on unitialized attr // and destroyed with pthread_attr_destroy when no longer needed. int pthread_getattr_np( pthread_t threadID, pthread_attr_t *attr ) libcfa_public __THROW { // GNU extension check_nonnull(attr); // copy all fields *get(attr) = lookup( threadID )->attr; return 0; } // pthread_getattr_np //######################### Threads ######################### int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW { cfaPthread *t = alloc(); (*t){_thread, attr, start_routine, arg}; return 0; } int pthread_join(pthread_t _thread, void **value_ptr) libcfa_public __THROW { // if thread is invalid if (_thread == NULL) return EINVAL; if (_thread == pthread_self()) return EDEADLK; // get user thr pointer cfaPthread* p = lookup(_thread); try { join(*p); } // if thread called pthread_exit catchResume (ThreadCancelled(cfaPthread) * cancel) {} // fetch result if (value_ptr != NULL ) *value_ptr = p->joinval; delete(p); return 0; } int pthread_tryjoin_np(pthread_t _thread, void **value_ptr) libcfa_public __THROW { // if thread is invalid if (_thread == NULL) return EINVAL; if (_thread == pthread_self()) return EDEADLK; cfaPthread* p = lookup(_thread); // thread not finished ? if (!p->isTerminated) return EBUSY; join( *p ); if (value_ptr != NULL ) *value_ptr = p->joinval; delete(p); return 0; } pthread_t pthread_self(void) libcfa_public __THROW { return (pthread_t)((uintptr_t)active_thread() - (sizeof(cfaPthread) - sizeof(thread$))); } void pthread_exit(void * status) libcfa_public __THROW { pthread_t pid = pthread_self(); cfaPthread* _thread = (cfaPthread*)pid; _thread->joinval = status; // set return value _thread->isTerminated = 1; // set terminated flag cancel_stack((pthread_exit_exp){&exp_vt}); } //pthread_exit_ int pthread_yield( void ) __THROW { // GNU extension yield(); return 0; } //######################### Mutex ######################### int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t *attr) libcfa_public __THROW { check_nonnull(_mutex); init(_mutex); return 0; } //pthread_mutex_init_ int pthread_mutex_destroy(pthread_mutex_t *_mutex) libcfa_public __THROW { check_nonnull(_mutex); simple_owner_lock* _lock = get(_mutex); if (_lock->owner != NULL){ return EBUSY; } destroy(_mutex); return 0; } //pthread_mutex_destroy_ int pthread_mutex_lock(pthread_mutex_t *_mutex) libcfa_public __THROW { check_nonnull(_mutex); mutex_check(_mutex); simple_owner_lock* _lock = get(_mutex); lock(*_lock); return 0; } //pthread_mutex_lock_ int pthread_mutex_unlock(pthread_mutex_t *_mutex) libcfa_public __THROW { check_nonnull(_mutex); simple_owner_lock* _lock = get(_mutex); if (_lock->owner != active_thread()){ return EPERM; } // current thread does not hold the mutex unlock(*_lock); return 0; } //pthread_mutex_unlock_ int pthread_mutex_trylock(pthread_mutex_t *_mutex) libcfa_public __THROW { check_nonnull(_mutex); simple_owner_lock* _lock = get(_mutex); if (_lock->owner != active_thread() && _lock->owner != NULL){ return EBUSY; } // if mutex is owned lock(*_lock); return 0; } //pthread_mutex_trylock_ //######################### Conditional Variable ######################### /* conditional variable routines */ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) libcfa_public __THROW { check_nonnull(cond); init(cond); return 0; } //pthread_cond_init int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *_mutex) libcfa_public __THROW { check_nonnull(_mutex); check_nonnull(cond); wait(*get(cond), *get(_mutex)); return 0; } // pthread_cond_wait int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * _mutex, const struct timespec * abstime) libcfa_public __THROW { check_nonnull(_mutex); check_nonnull(cond); wait(*get(cond), *get(_mutex), *abstime); return 0; } // pthread_cond_timedwait int pthread_cond_signal(pthread_cond_t *cond) libcfa_public __THROW { check_nonnull(cond); return notify_one(*get(cond)); } // pthread_cond_signal int pthread_cond_broadcast(pthread_cond_t *cond) libcfa_public __THROW { check_nonnull(cond); return notify_all(*get(cond)); } // pthread_cond_broadcast int pthread_cond_destroy(pthread_cond_t *cond) libcfa_public __THROW { check_nonnull(cond); destroy(cond); return 0; } // pthread_cond_destroy //######################### Local storage ######################### int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) libcfa_public __THROW { static_assert(sizeof(pthread_once_t) >= sizeof(int),"sizeof(pthread_once_t) < sizeof(int)"); check_nonnull(once_control); check_nonnull(init_routine); lock(once_lock); if ( *((int *)once_control) == 0 ) { init_routine(); *((int *)once_control) = 1; } // if unlock(once_lock); return 0; } // pthread_once int pthread_key_create( pthread_key_t *key, void (*destructor)( void * ) ) libcfa_public __THROW { lock(key_lock); for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) { if ( ! cfa_pthread_keys[i].in_use ) { cfa_pthread_keys[i].in_use = true; cfa_pthread_keys[i].destructor = destructor; unlock( key_lock ); *key = i; return 0; } // if } // for unlock(key_lock); return EAGAIN; } // pthread_key_create int pthread_key_delete( pthread_key_t key ) libcfa_public __THROW { lock(key_lock); if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) { unlock( key_lock ); return EINVAL; } // if cfa_pthread_keys[key].in_use = false; cfa_pthread_keys[key].destructor = NULL; // Remove key from all threads with a value. pthread_values& p; Sequence(pthread_values)& head = cfa_pthread_keys[key].threads; for ( SeqIter(pthread_values) iter = { head }; iter | p; ) { remove(head, p); p.in_use = false; } unlock(key_lock); return 0; } // pthread_key_delete int pthread_setspecific( pthread_key_t key, const void *value ) libcfa_public __THROW { // get current thread cfaPthread* t = lookup(pthread_self()); // if current thread's pthreadData is NULL; initialize it pthread_values* values; if (t->pthreadData == NULL){ values = anew( PTHREAD_KEYS_MAX); t->pthreadData = values; for (int i = 0;i < PTHREAD_KEYS_MAX; i++){ t->pthreadData[i].in_use = false; } // for } else { values = t->pthreadData; } // if // find corresponding key and set value lock(key_lock); // if invalid key if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) { unlock( key_lock ); return EINVAL; } // if pthread_values &entry = values[key]; if ( ! entry.in_use ) { entry.in_use = true; add(cfa_pthread_keys[key].threads, entry); } // if entry.value = (void *)value; unlock(key_lock); return 0; } //pthread_setspecific void* pthread_getspecific(pthread_key_t key) libcfa_public __THROW { if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL; // get current thread cfaPthread* t = lookup(pthread_self()); if (t->pthreadData == NULL) return NULL; lock(key_lock); pthread_values &entry = ((pthread_values *)t->pthreadData)[key]; if ( ! entry.in_use ) { unlock( key_lock ); return NULL; } // if void *value = entry.value; unlock(key_lock); return value; } //pthread_get_specific //######################### Parallelism ######################### void pthread_delete_kernel_threads_() __THROW { // see uMain::~uMain Pthread_kernel_threads& p; for ( StackIter(Pthread_kernel_threads) iter = {cfa_pthreads_kernel_threads}; iter | p; ) { delete(&p); } // for } // pthread_delete_kernel_threads_ int pthread_getconcurrency( void ) __THROW { // XOPEN extension return cfa_pthreads_kernel_threads_zero ? 0 : cfa_pthreads_no_kernel_threads; } // pthread_getconcurrency int pthread_setconcurrency( int new_level ) libcfa_public __THROW { // XOPEN extension if ( new_level < 0 ) return EINVAL; if ( new_level == 0 ) { cfa_pthreads_kernel_threads_zero = true; // remember set to zero, but ignore return 0; // do not do kernel thread management } // exit cfa_pthreads_kernel_threads_zero = false; lock( concurrency_lock ); for ( ; new_level > cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads += 1 ) { // add processors ? push(cfa_pthreads_kernel_threads, *new() ); } // for for ( ; new_level < cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads -= 1 ) { // remove processors ? delete(&pop(cfa_pthreads_kernel_threads)); } // for unlock( concurrency_lock ); return 0; } // pthread_setconcurrency //######################### Signal ######################### int pthread_sigmask( int /* how */, const sigset_t * /* set */, sigset_t * /* oset */ ) libcfa_public __THROW { abort( "pthread_sigmask : not implemented" ); return 0; } // pthread_sigmask int pthread_kill( pthread_t _thread __attribute__(( unused )), int sig ) libcfa_public __THROW { if ( sig == 0 ) { return 0; } else { abort( "pthread_kill : not implemented" ); } // if return 0; } // pthread_kill int pthread_sigqueue(pthread_t , int sig, const union sigval) libcfa_public __THROW { abort( "pthread_sigqueue : not implemented" ); return 0; } // pthread_sigqueue //######################### Scheduling ######################### int pthread_detach( pthread_t threadID ) __THROW { abort( "pthread_detach : not implemented" ); return 0; } // pthread_detach int pthread_setschedparam( pthread_t /* thread */, int /* policy */, const struct sched_param * /* param */ ) libcfa_public __THROW { abort( "pthread_setschedparam : not implemented" ); return 0; } // pthread_setschedparam int pthread_getschedparam( pthread_t /* thread */, int */* policy */, struct sched_param * /* param */ ) libcfa_public __THROW { abort( "pthread_getschedparam : not implemented" ); return 0; } // pthread_getschedparam //######################### Mutex Attr ######################### int pthread_mutexattr_init( pthread_mutexattr_t * /* attr */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_init int pthread_mutexattr_destroy( pthread_mutexattr_t * /* attr */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_destroy int pthread_mutexattr_setpshared( pthread_mutexattr_t * /* attr */, int /* pshared */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_setpshared int pthread_mutexattr_getpshared( const pthread_mutexattr_t * /* attr */, int * /* pshared */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_getpshared int pthread_mutexattr_setprotocol( pthread_mutexattr_t * /* attr */, int /* protocol */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_setprotocol int pthread_mutexattr_getprotocol( const pthread_mutexattr_t * /* attr */, int * /* protocol */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_getprotocol int pthread_mutexattr_setprioceiling( pthread_mutexattr_t * /* attr */, int /* prioceiling */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_setprioceiling int pthread_mutexattr_getprioceiling( const pthread_mutexattr_t * /* attr */, int * /* ceiling */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_getprioceiling int pthread_mutex_setprioceiling( pthread_mutex_t * /* mutex */, int /* prioceiling */, int * /* old_ceiling */ ) libcfa_public __THROW { return 0; } // pthread_mutex_setprioceiling int pthread_mutex_getprioceiling( const pthread_mutex_t * /* mutex */, int * /* ceiling */ ) libcfa_public __THROW { return 0; } // pthread_mutex_getprioceiling int pthread_mutexattr_gettype( __const pthread_mutexattr_t * __restrict /* __attr */, int * __restrict /* __kind */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_gettype int pthread_mutexattr_settype( pthread_mutexattr_t * /* __attr */, int /* __kind */ ) libcfa_public __THROW { return 0; } // pthread_mutexattr_settype //######################### Mutex ######################### int pthread_mutex_timedlock( pthread_mutex_t *__restrict /* __mutex */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW { abort( "pthread_mutex_timedlock" ); } // pthread_mutex_timedlock //######################### Condition ######################### int pthread_condattr_getclock( __const pthread_condattr_t * __restrict /* __attr */, __clockid_t *__restrict /* __clock_id */ ) libcfa_public __THROW { abort( "pthread_condattr_getclock" ); } // pthread_condattr_getclock int pthread_condattr_setclock( pthread_condattr_t * /* __attr */, __clockid_t /* __clock_id */ ) libcfa_public __THROW { abort( "pthread_condattr_setclock" ); } // pthread_condattr_setclock //######################### Spinlock ######################### int pthread_spin_init( pthread_spinlock_t * /* __lock */, int /*__pshared */ ) libcfa_public __THROW { abort( "pthread_spin_init" ); } // pthread_spin_init int pthread_spin_destroy( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW { abort( "pthread_spin_destroy" ); } // pthread_spin_destroy int pthread_spin_lock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW { abort( "pthread_spin_lock" ); } // pthread_spin_lock int pthread_spin_trylock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW { abort( "pthread_spin_trylock" ); } // pthread_spin_trylock int pthread_spin_unlock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW { abort( "pthread_spin_unlock" ); } // pthread_spin_unlock //######################### Barrier ######################### int pthread_barrier_init( pthread_barrier_t *__restrict /* __barrier */, __const pthread_barrierattr_t *__restrict /* __attr */, unsigned int /* __count */ ) libcfa_public __THROW { abort( "pthread_barrier_init" ); } // pthread_barrier_init int pthread_barrier_destroy( pthread_barrier_t * /* __barrier */ ) libcfa_public __THROW { abort( "pthread_barrier_destroy" ); } // pthread_barrier_destroy int pthread_barrier_wait( pthread_barrier_t * /* __barrier */ ) libcfa_public __THROW { abort( "pthread_barrier_wait" ); } // pthread_barrier_wait int pthread_barrierattr_init( pthread_barrierattr_t * /* __attr */ ) libcfa_public __THROW { abort( "pthread_barrierattr_init" ); } // pthread_barrierattr_init int pthread_barrierattr_destroy( pthread_barrierattr_t * /* __attr */ ) libcfa_public __THROW { abort( "pthread_barrierattr_destroy" ); } // pthread_barrierattr_destroy int pthread_barrierattr_getpshared( __const pthread_barrierattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) libcfa_public __THROW { abort( "pthread_barrierattr_getpshared" ); } // pthread_barrierattr_getpshared int pthread_barrierattr_setpshared( pthread_barrierattr_t * /* __attr */, int /* __pshared */ ) libcfa_public __THROW { abort( "pthread_barrierattr_setpshared" ); } // pthread_barrierattr_setpshared //######################### Clock ######################### int pthread_getcpuclockid( pthread_t /* __thread_id */, __clockid_t * /* __clock_id */ ) libcfa_public __THROW { abort( "pthread_getcpuclockid" ); } // pthread_getcpuclockid // pthread_atfork() // UNIX98 //######################### Read/Write ######################### int pthread_rwlock_init( pthread_rwlock_t *__restrict /* __rwlock */, __const pthread_rwlockattr_t *__restrict /* __attr */ ) libcfa_public __THROW { abort( "pthread_rwlock_init" ); } // pthread_rwlock_init int pthread_rwlock_destroy( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW { abort( "pthread_rwlock_destroy" ); } // pthread_rwlock_destroy int pthread_rwlock_rdlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW { abort( "pthread_rwlock_rdlock" ); } // pthread_rwlock_rdlock int pthread_rwlock_tryrdlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW { abort( "pthread_rwlock_tryrdlock" ); } // pthread_rwlock_tryrdlock int pthread_rwlock_wrlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW { abort( "pthread_rwlock_wrlock" ); } // pthread_rwlock_wrlock int pthread_rwlock_trywrlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW { abort( "pthread_rwlock_trywrlock" ); } // pthread_rwlock_trywrlock int pthread_rwlock_unlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW { abort( "pthread_rwlock_unlock" ); } // pthread_rwlock_unlock int pthread_rwlockattr_init( pthread_rwlockattr_t * /* __attr */ ) libcfa_public __THROW { abort( "pthread_rwlockattr_init" ); } // pthread_rwlockattr_init int pthread_rwlockattr_destroy( pthread_rwlockattr_t * /*__attr */ ) libcfa_public __THROW { abort( "pthread_rwlockattr_destroy" ); } // pthread_rwlockattr_destroy int pthread_rwlockattr_getpshared( __const pthread_rwlockattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) libcfa_public __THROW { abort( "pthread_rwlockattr_getpshared" ); } // pthread_rwlockattr_getpshared int pthread_rwlockattr_setpshared( pthread_rwlockattr_t * /* __attr */, int /* __pshared */ ) libcfa_public __THROW { abort( "pthread_rwlockattr_setpshared" ); } // pthread_rwlockattr_setpshared int pthread_rwlockattr_getkind_np( __const pthread_rwlockattr_t * /* __attr */, int * /* __pref */ ) libcfa_public __THROW { abort( "pthread_rwlockattr_getkind_np" ); } // pthread_rwlockattr_getkind_np int pthread_rwlockattr_setkind_np( pthread_rwlockattr_t * /* __attr */, int /* __pref */ ) libcfa_public __THROW { abort( "pthread_rwlockattr_setkind_np" ); } // pthread_rwlockattr_setkind_np // UNIX98 + XOPEN int pthread_rwlock_timedrdlock( pthread_rwlock_t *__restrict /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW { abort( "pthread_rwlock_timedrdlock" ); } // pthread_rwlock_timedrdlock int pthread_rwlock_timedwrlock( pthread_rwlock_t *__restrict /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW { abort( "pthread_rwlock_timedwrlock" ); } // pthread_rwlock_timedwrlock // GNU //######################### Parallelism ######################### int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { abort( "pthread_setaffinity_np" ); } // pthread_setaffinity_np int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { abort( "pthread_getaffinity_np" ); } // pthread_getaffinity_np int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { abort( "pthread_attr_setaffinity_np" ); } // pthread_attr_setaffinity_np int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { abort( "pthread_attr_getaffinity_np" ); } // pthread_attr_getaffinity_np //######################### Cancellation ######################### void _pthread_cleanup_push_defer( struct _pthread_cleanup_buffer * /* __buffer */, void( * /* __routine */ )( void * ), void * /* __arg */ ) libcfa_public __THROW { abort( "_pthread_cleanup_push_defer" ); } // _pthread_cleanup_push_defer void _pthread_cleanup_pop_restore( struct _pthread_cleanup_buffer * /* __buffer */, int /* __execute */ ) libcfa_public __THROW { abort( "_pthread_cleanup_pop_restore" ); } // _pthread_cleanup_pop_res int pthread_cancel( pthread_t threadID ) libcfa_public __THROW { abort("pthread cancel not implemented"); return 0; } // pthread_cancel int pthread_setcancelstate( int state, int *oldstate ) libcfa_public __THROW { abort("pthread_setcancelstate not implemented"); return 0; } // pthread_setcancelstate int pthread_setcanceltype( int type, int *oldtype ) libcfa_public __THROW { abort("pthread_setcanceltype not implemented"); return 0; } // pthread_setcanceltype } // extern "C" #pragma GCC diagnostic pop