Changeset 9cd5bd2


Ignore:
Timestamp:
Sep 22, 2022, 3:10:12 PM (18 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
df6cc9d
Parents:
95dab9e
Message:

Added an assembly to prevent null-checks from being optimized out.
Attempted to reduce the scope of needed headers.
Cleaned tabbing.

Location:
libcfa/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/defs.hfa

    r95dab9e r9cd5bd2  
    2121#include <stdint.h>
    2222#include <assert.h>
    23 #include <signal.h>
    2423
    2524#define likely(x)   __builtin_expect(!!(x), 1)
     
    5958void abort( bool signalAbort, const char fmt[], ... ) __attribute__ (( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    6059extern "C" {
     60#endif
    6161void __cabi_abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     62#ifdef __cforall
    6263}
    6364#endif
  • libcfa/src/concurrency/kernel/private.hfa

    r95dab9e r9cd5bd2  
    2020#endif
    2121
     22#include <signal.h>
     23
    2224#include "kernel.hfa"
    2325#include "thread.hfa"
  • libcfa/src/concurrency/pthread.cfa

    r95dab9e r9cd5bd2  
    1717#define _GNU_SOURCE
    1818
     19#include <signal.h>
    1920#include <pthread.h>
    2021#include <errno.h>
     
    2324
    2425
    25 #pragma GCC diagnostic push
    26 #pragma GCC diagnostic ignored "-Wnonnull-compare"
     26#define check_nonnull(x) asm("": "+rm"(x)); if( x == 0p ) return EINVAL;
    2727
    2828/* pthread key, pthread once inner routine mutual exclusion */
     
    3131//######################### Local Storage Helpers #########################
    3232
    33 #define PTHREADS_THR_MAX 256
    34 #define PTHREAD_KEYS_MAX 1024
     33enum { PTHREAD_KEYS_MAX = 1024 };
     34
    3535struct Pthread_values{
    36     inline Seqable;
    37     void* value;
    38     bool in_use;
     36        inline Seqable;
     37        void* value;
     38        bool in_use;
    3939};
    4040
    4141
    4242static Pthread_values *& Back( Pthread_values * n ) {
    43     return (Pthread_values *)Back( (Seqable *)n );
     43        return (Pthread_values *)Back( (Seqable *)n );
    4444}
    4545static Pthread_values *& Next( Pthread_values * n ) {
    46     return (Pthread_values *)Next( (Colable *)n );
     46        return (Pthread_values *)Next( (Colable *)n );
    4747}
    4848
    4949struct Pthread_keys{
    50     bool in_use;
    51     void (*destructor)( void * );
    52     Sequence(Pthread_values) threads;
     50        bool in_use;
     51        void (*destructor)( void * );
     52        Sequence(Pthread_values) threads;
    5353};  // Pthread keys
    5454
    5555static void ?{}(Pthread_keys& k){
    56     //sout | "inited";
    57     k.threads{};
     56        k.threads{};
    5857}
    5958
    6059// Create storage separately to ensure no constructors are called.
    61 //static char cfa_pthread_keys_storage[sizeof(Pthread_keys) * PTHREAD_KEYS_MAX] __attribute__((aligned (16))) = {0};
    6260static Pthread_keys cfa_pthread_keys_storage[PTHREAD_KEYS_MAX] __attribute__((aligned (16)));
    6361
    6462static void init_pthread_storage(){
    65     for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
    66         cfa_pthread_keys_storage[i]{};
    67     }
     63        for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
     64                cfa_pthread_keys_storage[i]{};
     65        }
    6866}
    6967
     
    7876
    7977struct Pthread_kernel_threads{
    80     inline Colable;
    81     processor p;
     78        inline Colable;
     79        processor p;
    8280};
    8381
    8482Pthread_kernel_threads *& Next( Pthread_kernel_threads * n ) {
    85     return (Pthread_kernel_threads *)Next( (Colable *)n );
     83        return (Pthread_kernel_threads *)Next( (Colable *)n );
    8684}
    8785
     
    9795/* condvar helper routines */
    9896static void init(pthread_cond_t* pcond){
    99     static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
    100     cfa2pthr_cond_var_t* _cond = (cfa2pthr_cond_var_t*)pcond;
    101     ?{}(*_cond);
     97        static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
     98        cfa2pthr_cond_var_t* _cond = (cfa2pthr_cond_var_t*)pcond;
     99        ?{}(*_cond);
    102100}
    103101
    104102static cfa2pthr_cond_var_t* get(pthread_cond_t* pcond){
    105     static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
    106     return (cfa2pthr_cond_var_t*)pcond;
     103        static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
     104        return (cfa2pthr_cond_var_t*)pcond;
    107105}
    108106
    109107static void destroy(pthread_cond_t* cond){
    110     static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
    111     ^?{}(*get(cond));
     108        static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)");
     109        ^?{}(*get(cond));
    112110}
    113111
     
    123121        // if pthread_mutex_t is initialized by PTHREAD_MUTEX_INITIALIZER, _lock_val should be 0
    124122        if ( _lock_val == 0 ) {                 // static initialized ?
    125             lock(magic_mutex_check);    // race
    126             _lock_val = ((pthread_mutex_t *)mutex_)->__data.__lock;
    127             if ( _lock_val == 0 ) {             // static initialized ?
     123                lock(magic_mutex_check);        // race
     124                _lock_val = ((pthread_mutex_t *)mutex_)->__data.__lock;
     125                if ( _lock_val == 0 ) {         // static initialized ?
    128126                pthread_mutex_init( t, NULL );
    129             } // if
    130             unlock(magic_mutex_check);  // race
     127                } // if
     128                unlock(magic_mutex_check);      // race
    131129        } // if
    132130} // mutex_check
     
    134132
    135133static void init(pthread_mutex_t* plock){
    136     static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
    137     simple_owner_lock* _lock = (simple_owner_lock*)plock;
    138     ?{}(*_lock);
     134        static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
     135        simple_owner_lock* _lock = (simple_owner_lock*)plock;
     136        ?{}(*_lock);
    139137}
    140138
    141139static simple_owner_lock* get(pthread_mutex_t* plock){
    142     static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
    143     return (simple_owner_lock*)plock;
     140        static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
     141        return (simple_owner_lock*)plock;
    144142}
    145143
    146144static void destroy(pthread_mutex_t* plock){
    147     static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
    148     ^?{}(*get(plock));
     145        static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)");
     146        ^?{}(*get(plock));
    149147}
    150148
     
    161159
    162160static const cfaPthread_attr_t default_attrs{
    163     0,
    164     0,
    165     (size_t)65000,
    166     (void *)NULL,
    167     0,
    168     0,
    169     {0}
     161        0,
     162        0,
     163        (size_t)65000,
     164        (void *)NULL,
     165        0,
     166        0,
     167        {0}
    170168};
    171169
     
    173171/*
    174172static const cfaPthread_attr_t default_attrs = {
    175     PTHREAD_SCOPE_SYSTEM,
    176     PTHREAD_CREATE_JOINABLE,
    177     (size_t)DEFAULT_STACK_SIZE,
    178     (void *)NULL,
    179     0,
    180     PTHREAD_EXPLICIT_SCHED,
    181     {0}
     173        PTHREAD_SCOPE_SYSTEM,
     174        PTHREAD_CREATE_JOINABLE,
     175        (size_t)DEFAULT_STACK_SIZE,
     176        (void *)NULL,
     177        0,
     178        PTHREAD_EXPLICIT_SCHED,
     179        {0}
    182180};
    183181*/
     
    186184
    187185static cfaPthread_attr_t* get(const pthread_attr_t* attr){
    188     static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t),"sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)");
    189     return (cfaPthread_attr_t*)attr;
     186        static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t),"sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)");
     187        return (cfaPthread_attr_t*)attr;
    190188}
    191189
     
    195193// exception for cancel_stack in pthread_exit
    196194exception pthread_exit_exp {};
    197 static vtable(pthread_exit_exp) exp;
     195static vtable(pthread_exit_exp) exp_vt;
    198196
    199197thread cfaPthread{
    200     cfaPthread_attr_t attr;
    201     pthread_t pthreadId;
    202     void *joinval;                                                                              // pthreads return value
     198        cfaPthread_attr_t attr;
     199        pthread_t pthreadId;
     200        void *joinval;                                                                          // pthreads return value
    203201        pthread_attr_t pthread_attr;                                            // pthread attributes
    204     void *(*start_routine)(void *);                     // routine start
    205     void *arg;                                                          // thread parameter                           
    206     Pthread_values* pthreadData;
    207     bool isTerminated;                                  // flag used for tryjoin
     202        void *(*start_routine)(void *);                     // routine start
     203        void *arg;                                                              // thread parameter
     204        Pthread_values* pthreadData;
     205        bool isTerminated;                                  // flag used for tryjoin
    208206};
    209207
     
    211209//  cfaPthread entry point
    212210void main(cfaPthread& _thread) with(_thread){
    213     joinval =  start_routine(arg);
    214     isTerminated = true;
     211        joinval =  start_routine(arg);
     212        isTerminated = true;
    215213}
    216214
    217215// generate pthread_t by cfaPthread ptr
    218216static pthread_t create( cfaPthread *p ) {
    219     static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)");
     217        static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)");
    220218        return (pthread_t)p;
    221219}
    222220
    223221static cfaPthread *lookup( pthread_t p ){
    224     static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)");
    225     return (cfaPthread*)p;
     222        static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)");
     223        return (cfaPthread*)p;
    226224}
    227225
    228226static void pthread_deletespecific_( Pthread_values* values )  { // see uMachContext::invokeTask
    229     Pthread_values* value;
    230     Pthread_keys* key;
    231     bool destcalled = true;
    232     if (values != NULL){
    233         for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) {
    234             destcalled = false;
    235             lock(key_lock);
    236             for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
    237                 // for each valid key
    238                 if ( values[i].in_use){
    239                     value = &values[i];
    240                     key = &cfa_pthread_keys[i];
    241                     value->in_use = false;
    242                     remove(key->threads, *value);
    243                     // if  a  key  value  has  a  non-NULL  destructor pointer,  and  the  thread  has  a  non-NULL  value associated with that key,
    244                     // 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.
    245                     if (value->value != NULL && key->destructor != NULL){
    246                         unlock(key_lock);
    247                         key->destructor(value->value); // run destructor
    248                         lock(key_lock);
    249                         destcalled = true;
    250                     }   // if
    251                     value->value = NULL;
    252                 }   // if
    253             }   // for
    254             unlock(key_lock);
    255         }   // for
    256         free(values);
    257     }   // if
     227        Pthread_values* value;
     228        Pthread_keys* key;
     229        bool destcalled = true;
     230        if (values != NULL){
     231                for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) {
     232                        destcalled = false;
     233                        lock(key_lock);
     234                        for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
     235                                // for each valid key
     236                                if ( values[i].in_use){
     237                                        value = &values[i];
     238                                        key = &cfa_pthread_keys[i];
     239                                        value->in_use = false;
     240                                        remove(key->threads, *value);
     241                                        // if  a  key  value  has  a  non-NULL  destructor pointer,  and  the  thread  has  a  non-NULL  value associated with that key,
     242                                        // 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.
     243                                        if (value->value != NULL && key->destructor != NULL){
     244                                                unlock(key_lock);
     245                                                key->destructor(value->value); // run destructor
     246                                                lock(key_lock);
     247                                                destcalled = true;
     248                                        }   // if
     249                                        value->value = NULL;
     250                                }   // if
     251                        }   // for
     252                        unlock(key_lock);
     253                }   // for
     254                free(values);
     255        }   // if
    258256}
    259257
    260258static void ^?{}(cfaPthread & mutex t){
    261     // delete pthread local storage
    262     Pthread_values* values = t.pthreadData;
    263     pthread_deletespecific_(values);
     259        // delete pthread local storage
     260        Pthread_values* values = t.pthreadData;
     261        pthread_deletespecific_(values);
    264262}
    265263
    266264static void ?{}(cfaPthread &t, pthread_t* _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) {
    267    
    268     // set up user thread stackSize
    269     cfaPthread_attr_t * attr = get(_attr);
    270     ((thread&)t){ attr ? attr->stacksize: DEFAULT_STACK_SIZE };
    271 
    272     // initialize _thread & cfaPthread id
    273     t.pthreadId = create(&t);
    274     *_thread = t.pthreadId;
    275 
    276     // if attr null, self attr will be set as default_attrs; else set to attr
    277     t.attr = (attr != NULL ? *attr : default_attrs);
    278 
    279     // init start routine and arguments
    280     t.start_routine = start_routine;
    281     t.arg = arg;
    282     t.pthreadData = NULL;
     265
     266        // set up user thread stackSize
     267        cfaPthread_attr_t * attr = get(_attr);
     268        ((thread&)t){ attr ? attr->stacksize: DEFAULT_STACK_SIZE };
     269
     270        // initialize _thread & cfaPthread id
     271        t.pthreadId = create(&t);
     272        *_thread = t.pthreadId;
     273
     274        // if attr null, self attr will be set as default_attrs; else set to attr
     275        t.attr = (attr != NULL ? *attr : default_attrs);
     276
     277        // init start routine and arguments
     278        t.start_routine = start_routine;
     279        t.arg = arg;
     280        t.pthreadData = NULL;
    283281}   // not used
    284282
    285283
    286284extern "C"{
    287     //######################### Pthread Attrs #########################
    288 
    289     int pthread_attr_init(pthread_attr_t *attr) libcfa_public __THROW {
    290         cfaPthread_attr_t* _attr = get(attr);
    291         ?{}(*_attr);
    292         *_attr = default_attrs;
    293         return 0;
    294     }
    295     int pthread_attr_destroy(pthread_attr_t *attr) libcfa_public __THROW {
    296         ^?{}(*get(attr));
    297         return 0;
    298     }
    299    
    300     int pthread_attr_setscope( pthread_attr_t *attr, int contentionscope ) libcfa_public __THROW {
    301         get( attr )->contentionscope = contentionscope;
    302         return 0;
    303     } // pthread_attr_setscope
    304 
    305     int pthread_attr_getscope( const pthread_attr_t *attr, int *contentionscope ) libcfa_public __THROW {
    306         *contentionscope = get( attr )->contentionscope;
    307         return 0;
    308     } // pthread_attr_getscope
    309 
    310     int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate ) libcfa_public __THROW {
    311         get( attr )->detachstate = detachstate;
    312         return 0;
    313     } // pthread_attr_setdetachstate
    314 
    315     int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ) libcfa_public __THROW {
    316         *detachstate = get( attr )->detachstate;
    317         return 0;
    318     } // pthread_attr_getdetachstate
    319 
    320     int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ) libcfa_public __THROW {
    321         get( attr )->stacksize = stacksize;
    322         return 0;
    323     } // pthread_attr_setstacksize
    324 
    325     int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ) libcfa_public __THROW {
    326         *stacksize = get( attr )->stacksize;
    327         return 0;
    328     } // pthread_attr_getstacksize
    329 
    330     int pthread_attr_getguardsize( const pthread_attr_t * /* attr */, size_t * /* guardsize */ ) libcfa_public __THROW {
    331             return 0;
    332     } // pthread_attr_getguardsize
    333 
    334     int pthread_attr_setguardsize( pthread_attr_t * /* attr */, size_t /* guardsize */ ) libcfa_public __THROW {
    335             return 0;
    336     } // pthread_attr_setguardsize
    337 
    338     int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ) libcfa_public __THROW {
    339         get( attr )->stackaddr = stackaddr;
    340         return 0;
    341     } // pthread_attr_setstackaddr
    342 
    343     int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ) libcfa_public __THROW {
    344         *stackaddr = get( attr )->stackaddr;
    345         return 0;
    346     } // pthread_attr_getstackaddr
    347 
    348     int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW {
    349         get( attr )->stackaddr = stackaddr;
    350         get( attr )->stacksize = stacksize;
    351             return 0;
    352     } // pthread_attr_setstack
    353 
    354     int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize ) libcfa_public __THROW {
    355         *stackaddr = get( attr )->stackaddr;
    356         *stacksize = get( attr )->stacksize;
    357         return 0;
    358     } // pthread_attr_getstack
    359 
    360     // Initialize thread attribute *attr with attributes corresponding to the
    361     // already running thread threadID. It shall be called on unitialized attr
    362     // and destroyed with pthread_attr_destroy when no longer needed.
    363     int pthread_getattr_np( pthread_t threadID, pthread_attr_t *attr ) libcfa_public __THROW { // GNU extension
    364         // race condition during copy
    365         cfaPthread_attr_t* _attr = get(attr);
    366         ?{}(*_attr);
    367         if (_attr == NULL){
    368             return ENOMEM;
    369         }   // if
    370         *_attr = lookup( threadID )->attr; // copy all fields
    371             return 0;
    372     } // pthread_getattr_np
    373 
    374 
    375     //######################### Threads #########################
    376 
    377     int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW {
    378         cfaPthread *t = alloc();
    379         (*t){_thread, attr, start_routine, arg};
    380         //init_user_pthread(*t, _thread, attr, start_routine, arg);
    381         if (t == NULL) return EAGAIN; //no resource
    382         return 0;
    383     }   //pthread_create_
    384 
    385 
    386     int pthread_join(pthread_t _thread, void **value_ptr) libcfa_public __THROW {
    387         if (_thread == NULL) return EINVAL;   // if thread is invalid
    388         if (_thread == pthread_self()) return EDEADLK;
    389         cfaPthread* p = lookup(_thread);    // get user thr pointer   
    390         try {
    391             join(*p);
    392         } catchResume (ThreadCancelled(cfaPthread) * cancel) {} // if thread called pthread_exit
    393         if (value_ptr != NULL ) *value_ptr = p->joinval;   // fetch result
    394         delete(p);
    395         return 0;
    396     }   //pthread_join_
    397 
    398     int pthread_tryjoin_np(pthread_t _thread, void **value_ptr) libcfa_public __THROW {
    399         if (_thread == NULL) return EINVAL;  // if thread is invalid
    400         if (_thread == pthread_self()) return EDEADLK;
    401         cfaPthread* p = lookup(_thread);
    402         if (!p->isTerminated) return EBUSY; // thread not finished ?
    403         join( *p );
    404         if (value_ptr != NULL ) *value_ptr = p->joinval;
    405         delete(p);
    406         return 0;
    407     }   //pthread_join_
    408 
    409     pthread_t pthread_self(void) libcfa_public __THROW {
    410         return (pthread_t)((char*)active_thread()-(sizeof(cfaPthread)-sizeof(thread$)));
    411     }   //pthread_self_
    412 
    413     void pthread_exit(void * status) libcfa_public __THROW {
    414         pthread_t pid = pthread_self();
    415         cfaPthread* _thread = (cfaPthread*)pid;
    416         _thread->joinval = status;  // set return value
    417         _thread->isTerminated = 1;  // set terminated flag
    418         cancel_stack((pthread_exit_exp){&exp});
    419     }   //pthread_exit_
    420 
    421     int pthread_yield( void ) __THROW {                 // GNU extension
    422         yield();
    423         return 0;
    424     }
    425 
    426 
    427     //######################### Mutex #########################
    428 
    429     int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t *attr) libcfa_public __THROW {
    430         if (_mutex == NULL) return EINVAL;
    431 
    432         init(_mutex);
    433         return 0;
    434     }   //pthread_mutex_init_
    435 
    436 
    437     int pthread_mutex_destroy(pthread_mutex_t *_mutex) libcfa_public __THROW{
    438         if (_mutex == NULL){
    439              return EINVAL;
    440         }   // if mutex invalid
    441         simple_owner_lock* _lock = get(_mutex);
    442         if (_lock->owner != NULL){
    443             return EBUSY;
    444         }
    445         destroy(_mutex);
    446         return 0;
    447     }   //pthread_mutex_destroy_
    448 
    449     int pthread_mutex_lock(pthread_mutex_t *_mutex) libcfa_public __THROW{
    450         if (_mutex == NULL) {
    451             return EINVAL;
    452         }   // if mutex invalid
    453         mutex_check(_mutex);
    454         simple_owner_lock* _lock = get(_mutex);
    455         lock(*_lock);
    456         return 0;
    457     }   //pthread_mutex_lock_
    458 
    459     int pthread_mutex_unlock(pthread_mutex_t *_mutex) libcfa_public __THROW{
    460         if (_mutex == NULL) {
    461             return EINVAL;
    462         } // invalid mutex
    463         simple_owner_lock* _lock = get(_mutex);
    464         if (_lock->owner != active_thread()){
    465             return EPERM;
    466         } // current thread does not hold the mutex
    467         unlock(*_lock);
    468         return 0;
    469     }   //pthread_mutex_unlock_
    470 
    471     int pthread_mutex_trylock(pthread_mutex_t *_mutex) libcfa_public __THROW{
    472         if (_mutex == NULL) {
    473             return EINVAL;
    474         }   // if mutex invalid
    475         simple_owner_lock* _lock = get(_mutex);
    476         if (_lock->owner != active_thread() && _lock->owner != NULL){
    477             return EBUSY;
    478         }   // if mutex is owned
    479         lock(*_lock);
    480         return 0;
    481     }   //pthread_mutex_trylock_
    482 
    483     //######################### Conditional Variable #########################
    484 
    485     /* conditional variable routines */
    486     int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) libcfa_public __THROW {
    487         if (cond == NULL) return EINVAL;
    488         init(cond);
    489         return 0;
    490     }  //pthread_cond_init
    491 
    492     int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *_mutex) libcfa_public __THROW {
    493         if (cond == NULL || _mutex == NULL){
    494             return EINVAL;
    495         }   // invalid cond
    496         wait(*get(cond), *get(_mutex));
    497         return 0;
    498     } // pthread_cond_wait
    499 
    500     int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * _mutex, const struct timespec * abstime) libcfa_public __THROW {
    501         if (cond == NULL || _mutex == NULL){
    502             return EINVAL;
    503         }   // invalid cond
    504         wait(*get(cond), *get(_mutex), *abstime);
    505         return 0;
    506     } // pthread_cond_timedwait
    507 
    508     int pthread_cond_signal(pthread_cond_t *cond) libcfa_public __THROW {
    509         if (cond == NULL){
    510             return EINVAL;
    511         }   // invalid cond
    512         return notify_one(*get(cond));
    513     } // pthread_cond_signal
    514 
    515     int pthread_cond_broadcast(pthread_cond_t *cond) libcfa_public __THROW {
    516         if (cond == NULL){
    517             return EINVAL;
    518         }   // invalid cond
    519         return notify_all(*get(cond));
    520     } // pthread_cond_broadcast
    521 
    522     int pthread_cond_destroy(pthread_cond_t *cond) libcfa_public __THROW {
    523         if (cond == NULL){
    524             return EINVAL;
    525         }   // invalid cond
    526         destroy(cond);
    527         return 0;
    528     } // pthread_cond_destroy
    529 
    530 
    531 
    532     //######################### Local storage #########################
    533 
    534     int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) libcfa_public __THROW {
    535         static_assert(sizeof(pthread_once_t) >= sizeof(int),"sizeof(pthread_once_t) < sizeof(int)");
    536         if (once_control == NULL){
    537             return EINVAL;
    538         }
    539         if (init_routine == NULL){
    540             return EINVAL;
    541         }
    542         lock(once_lock);
    543         if ( *((int *)once_control) == 0 ) {
    544             init_routine();
    545             *((int *)once_control) = 1;
    546             } // if
    547         unlock(once_lock);
    548         return 0;
    549     } // pthread_once
    550 
    551     int pthread_key_create( pthread_key_t *key, void (*destructor)( void * ) ) libcfa_public __THROW {
    552         lock(key_lock);
    553         for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) {
    554             if ( ! cfa_pthread_keys[i].in_use ) {
    555                 cfa_pthread_keys[i].in_use = true;
    556                 cfa_pthread_keys[i].destructor = destructor;
    557                 unlock( key_lock );
    558                 *key = i;
    559                 return 0;
    560             } // if
    561         } // for
    562         unlock(key_lock);
    563         return EAGAIN;
    564     }   // pthread_key_create
    565 
    566     int pthread_key_delete( pthread_key_t key ) libcfa_public __THROW {
    567         lock(key_lock);
    568         if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) {
    569             unlock( key_lock );
    570             return EINVAL;
    571         } // if
    572         cfa_pthread_keys[key].in_use = false;
    573         cfa_pthread_keys[key].destructor = NULL;
    574 
    575         // Remove key from all threads with a value.
    576         Pthread_values& p;
    577         Sequence(Pthread_values)& head = cfa_pthread_keys[key].threads;
    578         for ( SeqIter(Pthread_values) iter = { head }; iter | p; ) {
    579             remove(head, p);
    580             p.in_use = false;
    581         }
    582         unlock(key_lock);
    583         return 0;
    584     }   // pthread_key_delete
    585 
    586     int pthread_setspecific( pthread_key_t key, const void *value ) libcfa_public __THROW {
    587         // get current thread
    588         cfaPthread* t = lookup(pthread_self());
    589         // if current thread's pthreadData is NULL; initialize it
    590         Pthread_values* values;
    591         if (t->pthreadData == NULL){
    592             values = anew( PTHREAD_KEYS_MAX);
    593             t->pthreadData = values;
    594             for (int i = 0;i < PTHREAD_KEYS_MAX; i++){
    595                 t->pthreadData[i].in_use = false;
    596             }   // for
    597         }   else {
    598             values = t->pthreadData;
    599         }   // if
    600         // find corresponding key and set value
    601         lock(key_lock);
    602         // if invalid key
    603         if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) {
    604             unlock( key_lock );
    605             return EINVAL;
    606         } // if
    607         Pthread_values &entry = values[key];
    608         if ( ! entry.in_use ) {
    609             entry.in_use = true;
    610             add(cfa_pthread_keys[key].threads, entry);
    611         } // if
    612         entry.value = (void *)value;
    613         unlock(key_lock);
    614         return 0;
    615     } //pthread_setspecific
    616 
    617     void* pthread_getspecific(pthread_key_t key) libcfa_public __THROW {
    618         if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL;
    619 
    620         // get current thread
    621         cfaPthread* t = lookup(pthread_self());
    622         if (t->pthreadData == NULL) return NULL;
    623         lock(key_lock);
    624         Pthread_values &entry = ((Pthread_values *)t->pthreadData)[key];
    625         if ( ! entry.in_use ) {
    626             unlock( key_lock );
    627             return NULL;
    628         } // if
    629             void *value = entry.value;
    630         unlock(key_lock);
    631 
    632         return value;
    633     }   //pthread_get_specific
    634 
    635     //######################### Parallelism #########################
    636     void pthread_delete_kernel_threads_() libcfa_public __THROW {       // see uMain::~uMain
    637         Pthread_kernel_threads& p;
    638         for ( StackIter(Pthread_kernel_threads) iter = {cfa_pthreads_kernel_threads}; iter | p; ) {
    639             delete(&p);
    640         } // for
    641     } // pthread_delete_kernel_threads_
    642 
    643     int pthread_getconcurrency( void ) libcfa_public __THROW {  // XOPEN extension
    644             return cfa_pthreads_kernel_threads_zero ? 0 : cfa_pthreads_no_kernel_threads;
    645     } // pthread_getconcurrency
    646 
    647     int pthread_setconcurrency( int new_level ) libcfa_public __THROW { // XOPEN extension
    648       if ( new_level < 0 ) return EINVAL;
    649       if ( new_level == 0 ) {
    650         cfa_pthreads_kernel_threads_zero = true;        // remember set to zero, but ignore
    651         return 0;                                       // do not do kernel thread management
    652       } // exit
    653       cfa_pthreads_kernel_threads_zero = false;
    654       lock( concurrency_lock );
    655       for ( ; new_level > cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads += 1 ) { // add processors ?
    656         push(cfa_pthreads_kernel_threads, *new() );
    657       } // for
    658       for ( ; new_level < cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads -= 1 ) { // remove processors ?
    659         delete(&pop(cfa_pthreads_kernel_threads));
    660       } // for
    661       unlock( concurrency_lock );
    662       return 0;
    663     } // pthread_setconcurrency
    664 
    665     //######################### Signal #########################
    666 
    667 
    668      int pthread_sigmask( int /* how */, const sigset_t * /* set */, sigset_t * /* oset */ ) libcfa_public __THROW {
    669              return 0;
    670      } // pthread_sigmask
    671 
    672     int pthread_kill( pthread_t _thread __attribute__(( unused )), int sig ) libcfa_public __THROW {
    673         if ( sig == 0 ) {
    674             return 0;
    675         } else {
    676             abort( "pthread_kill : not implemented" );
    677         } // if
    678         return 0;
    679     } // pthread_kill
    680 
    681     int pthread_sigqueue(pthread_t , int sig, const union sigval) libcfa_public __THROW {
    682         return 0;
    683     } // pthread_sigqueue
    684 
    685     //######################### Scheduling #########################
    686     int pthread_detach( pthread_t threadID ) __THROW {
    687         abort( "pthread_detach" );
    688         return 0;
    689     } // pthread_detach
    690 
    691     int pthread_setschedparam( pthread_t /* thread */, int /* policy */, const struct sched_param * /* param */ ) libcfa_public __THROW {
    692         abort( "pthread_setschedparam : not implemented" );
    693         return 0;
    694     } // pthread_setschedparam
    695 
    696     int pthread_getschedparam( pthread_t /* thread */, int */* policy */, struct sched_param * /* param */ ) libcfa_public __THROW {
    697         abort( "pthread_getschedparam : not implemented" );
    698         return 0;
    699     } // pthread_getschedparam
    700 
    701      //######################### Mutex Attr #########################
    702 
    703     int pthread_mutexattr_init( pthread_mutexattr_t * /* attr */ ) libcfa_public __THROW {
    704             return 0;
    705     } // pthread_mutexattr_init
    706 
    707     int pthread_mutexattr_destroy( pthread_mutexattr_t * /* attr */ ) libcfa_public __THROW {
    708         return 0;
    709     } // pthread_mutexattr_destroy
    710 
    711     int pthread_mutexattr_setpshared( pthread_mutexattr_t * /* attr */, int /* pshared */ ) libcfa_public __THROW {
    712         return 0;
    713     } // pthread_mutexattr_setpshared
    714 
    715     int pthread_mutexattr_getpshared( const pthread_mutexattr_t * /* attr */, int * /* pshared */ ) libcfa_public __THROW {
    716         return 0;
    717     } // pthread_mutexattr_getpshared
    718 
    719     int pthread_mutexattr_setprotocol( pthread_mutexattr_t * /* attr */, int /* protocol */ ) libcfa_public __THROW {
    720         return 0;
    721     } // pthread_mutexattr_setprotocol
    722 
    723     int pthread_mutexattr_getprotocol( const pthread_mutexattr_t * /* attr */, int * /* protocol */ ) libcfa_public __THROW {
    724         return 0;
    725     } // pthread_mutexattr_getprotocol
    726 
    727     int pthread_mutexattr_setprioceiling( pthread_mutexattr_t * /* attr */, int /* prioceiling */ ) libcfa_public __THROW {
    728         return 0;
    729     } // pthread_mutexattr_setprioceiling
    730 
    731     int pthread_mutexattr_getprioceiling( const pthread_mutexattr_t * /* attr */, int * /* ceiling */ ) libcfa_public __THROW {
    732         return 0;
    733     } // pthread_mutexattr_getprioceiling
    734 
    735     int pthread_mutex_setprioceiling( pthread_mutex_t * /* mutex */, int /* prioceiling */, int * /* old_ceiling */ ) libcfa_public __THROW {
    736         return 0;
    737     } // pthread_mutex_setprioceiling
    738 
    739     int pthread_mutex_getprioceiling( const pthread_mutex_t * /* mutex */, int * /* ceiling */ ) libcfa_public __THROW {
    740         return 0;
    741     } // pthread_mutex_getprioceiling
    742 
    743     int pthread_mutexattr_gettype( __const pthread_mutexattr_t * __restrict /* __attr */, int * __restrict /* __kind */ ) libcfa_public __THROW {
    744         return 0;
    745     } // pthread_mutexattr_gettype
    746 
    747     int pthread_mutexattr_settype( pthread_mutexattr_t * /* __attr */, int /* __kind */ ) libcfa_public __THROW {
    748         return 0;
    749     } // pthread_mutexattr_settype
    750 
    751     //######################### Mutex #########################
    752 
    753     int pthread_mutex_timedlock( pthread_mutex_t *__restrict /* __mutex */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW {
    754             abort( "pthread_mutex_timedlock" );
    755     } // pthread_mutex_timedlock
    756 
    757     //######################### Condition #########################
    758 
    759     int pthread_condattr_getclock( __const pthread_condattr_t * __restrict /* __attr */, __clockid_t *__restrict /* __clock_id */ ) libcfa_public __THROW {
    760             abort( "pthread_condattr_getclock" );
    761     } // pthread_condattr_getclock
    762 
    763     int pthread_condattr_setclock( pthread_condattr_t * /* __attr */, __clockid_t /* __clock_id */ ) libcfa_public __THROW {
    764             abort( "pthread_condattr_setclock" );
    765     } // pthread_condattr_setclock
    766 
    767     //######################### Spinlock #########################
    768 
    769     int pthread_spin_init( pthread_spinlock_t * /* __lock */, int /*__pshared */ ) libcfa_public __THROW {
    770             abort( "pthread_spin_init" );
    771     } // pthread_spin_init
    772 
    773     int pthread_spin_destroy( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
    774             abort( "pthread_spin_destroy" );
    775     } // pthread_spin_destroy
    776 
    777     int pthread_spin_lock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
    778             abort( "pthread_spin_lock" );
    779     } // pthread_spin_lock
    780 
    781     int pthread_spin_trylock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
    782             abort( "pthread_spin_trylock" );
    783     } // pthread_spin_trylock
    784 
    785     int pthread_spin_unlock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
    786             abort( "pthread_spin_unlock" );
    787     } // pthread_spin_unlock
    788 
    789     //######################### Barrier #########################
    790 
    791     int pthread_barrier_init( pthread_barrier_t *__restrict /* __barrier */, __const pthread_barrierattr_t *__restrict /* __attr */, unsigned int /* __count */ ) libcfa_public __THROW {
    792             abort( "pthread_barrier_init" );
    793     } // pthread_barrier_init
    794 
    795     int pthread_barrier_destroy( pthread_barrier_t * /* __barrier */ ) libcfa_public  __THROW {
    796             abort( "pthread_barrier_destroy" );
    797     } // pthread_barrier_destroy
    798 
    799     int pthread_barrier_wait( pthread_barrier_t * /* __barrier */ ) libcfa_public __THROW {
    800             abort( "pthread_barrier_wait" );
    801     } // pthread_barrier_wait
    802 
    803     int pthread_barrierattr_init( pthread_barrierattr_t * /* __attr */ ) libcfa_public __THROW {
    804             abort( "pthread_barrierattr_init" );
    805     } // pthread_barrierattr_init
    806 
    807     int pthread_barrierattr_destroy( pthread_barrierattr_t * /* __attr */ ) libcfa_public __THROW {
    808             abort( "pthread_barrierattr_destroy" );
    809     } // pthread_barrierattr_destroy
    810 
    811     int pthread_barrierattr_getpshared( __const pthread_barrierattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) libcfa_public __THROW {
    812             abort( "pthread_barrierattr_getpshared" );
    813     } // pthread_barrierattr_getpshared
    814 
    815     int pthread_barrierattr_setpshared( pthread_barrierattr_t * /* __attr */, int /* __pshared */ ) libcfa_public __THROW {
    816             abort( "pthread_barrierattr_setpshared" );
    817     } // pthread_barrierattr_setpshared
    818 
    819     //######################### Clock #########################
    820 
    821     int pthread_getcpuclockid( pthread_t /* __thread_id */, __clockid_t * /* __clock_id */ ) libcfa_public __THROW {
    822             abort( "pthread_getcpuclockid" );
    823     } // pthread_getcpuclockid
    824 
    825     // pthread_atfork()
     285        //######################### Pthread Attrs #########################
     286
     287        int pthread_attr_init(pthread_attr_t *attr) libcfa_public __THROW {
     288                cfaPthread_attr_t* _attr = get(attr);
     289                ?{}(*_attr);
     290                *_attr = default_attrs;
     291                return 0;
     292        }
     293        int pthread_attr_destroy(pthread_attr_t *attr) libcfa_public __THROW {
     294                ^?{}(*get(attr));
     295                return 0;
     296        }
     297
     298        int pthread_attr_setscope( pthread_attr_t *attr, int contentionscope ) libcfa_public __THROW {
     299                get( attr )->contentionscope = contentionscope;
     300                return 0;
     301        } // pthread_attr_setscope
     302
     303        int pthread_attr_getscope( const pthread_attr_t *attr, int *contentionscope ) libcfa_public __THROW {
     304                *contentionscope = get( attr )->contentionscope;
     305                return 0;
     306        } // pthread_attr_getscope
     307
     308        int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate ) libcfa_public __THROW {
     309                get( attr )->detachstate = detachstate;
     310                return 0;
     311        } // pthread_attr_setdetachstate
     312
     313        int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ) libcfa_public __THROW {
     314                *detachstate = get( attr )->detachstate;
     315                return 0;
     316        } // pthread_attr_getdetachstate
     317
     318        int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ) libcfa_public __THROW {
     319                get( attr )->stacksize = stacksize;
     320                return 0;
     321        } // pthread_attr_setstacksize
     322
     323        int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ) libcfa_public __THROW {
     324                *stacksize = get( attr )->stacksize;
     325                return 0;
     326        } // pthread_attr_getstacksize
     327
     328        int pthread_attr_getguardsize( const pthread_attr_t * /* attr */, size_t * /* guardsize */ ) libcfa_public __THROW {
     329                return 0;
     330        } // pthread_attr_getguardsize
     331
     332        int pthread_attr_setguardsize( pthread_attr_t * /* attr */, size_t /* guardsize */ ) libcfa_public __THROW {
     333                return 0;
     334        } // pthread_attr_setguardsize
     335
     336        int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ) libcfa_public __THROW {
     337                get( attr )->stackaddr = stackaddr;
     338                return 0;
     339        } // pthread_attr_setstackaddr
     340
     341        int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ) libcfa_public __THROW {
     342                *stackaddr = get( attr )->stackaddr;
     343                return 0;
     344        } // pthread_attr_getstackaddr
     345
     346        int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW {
     347                get( attr )->stackaddr = stackaddr;
     348                get( attr )->stacksize = stacksize;
     349                return 0;
     350        } // pthread_attr_setstack
     351
     352        int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize ) libcfa_public __THROW {
     353                *stackaddr = get( attr )->stackaddr;
     354                *stacksize = get( attr )->stacksize;
     355                return 0;
     356        } // pthread_attr_getstack
     357
     358        // Initialize thread attribute *attr with attributes corresponding to the
     359        // already running thread threadID. It shall be called on unitialized attr
     360        // and destroyed with pthread_attr_destroy when no longer needed.
     361        int pthread_getattr_np( pthread_t threadID, pthread_attr_t *attr ) libcfa_public __THROW { // GNU extension
     362                // race condition during copy
     363                cfaPthread_attr_t* _attr = get(attr);
     364                ?{}(*_attr);
     365                if (_attr == NULL){
     366                        return ENOMEM;
     367                }   // if
     368                *_attr = lookup( threadID )->attr; // copy all fields
     369                return 0;
     370        } // pthread_getattr_np
     371
     372
     373        //######################### Threads #########################
     374
     375        int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW {
     376                cfaPthread *t = alloc();
     377                (*t){_thread, attr, start_routine, arg};
     378                //init_user_pthread(*t, _thread, attr, start_routine, arg);
     379                if (t == NULL) return EAGAIN; //no resource
     380                return 0;
     381        }   //pthread_create_
     382
     383
     384        int pthread_join(pthread_t _thread, void **value_ptr) libcfa_public __THROW {
     385                if (_thread == NULL) return EINVAL;   // if thread is invalid
     386                if (_thread == pthread_self()) return EDEADLK;
     387                cfaPthread* p = lookup(_thread);    // get user thr pointer
     388                try {
     389                        join(*p);
     390                } catchResume (ThreadCancelled(cfaPthread) * cancel) {} // if thread called pthread_exit
     391                if (value_ptr != NULL ) *value_ptr = p->joinval;   // fetch result
     392                delete(p);
     393                return 0;
     394        }   //pthread_join_
     395
     396        int pthread_tryjoin_np(pthread_t _thread, void **value_ptr) libcfa_public __THROW {
     397                if (_thread == NULL) return EINVAL;  // if thread is invalid
     398                if (_thread == pthread_self()) return EDEADLK;
     399                cfaPthread* p = lookup(_thread);
     400                if (!p->isTerminated) return EBUSY; // thread not finished ?
     401                join( *p );
     402                if (value_ptr != NULL ) *value_ptr = p->joinval;
     403                delete(p);
     404                return 0;
     405        }   //pthread_join_
     406
     407        pthread_t pthread_self(void) libcfa_public __THROW {
     408                return (pthread_t)((char*)active_thread()-(sizeof(cfaPthread)-sizeof(thread$)));
     409        }   //pthread_self_
     410
     411        void pthread_exit(void * status) libcfa_public __THROW {
     412                pthread_t pid = pthread_self();
     413                cfaPthread* _thread = (cfaPthread*)pid;
     414                _thread->joinval = status;  // set return value
     415                _thread->isTerminated = 1;  // set terminated flag
     416                cancel_stack((pthread_exit_exp){&exp_vt});
     417        }   //pthread_exit_
     418
     419        int pthread_yield( void ) __THROW {                     // GNU extension
     420                yield();
     421                return 0;
     422        }
     423
     424
     425        //######################### Mutex #########################
     426
     427        int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t *attr) libcfa_public __THROW {
     428                check_nonnull(_mutex);
     429                init(_mutex);
     430                return 0;
     431        }   //pthread_mutex_init_
     432
     433
     434        int pthread_mutex_destroy(pthread_mutex_t *_mutex) libcfa_public __THROW {
     435                check_nonnull(_mutex);
     436                simple_owner_lock* _lock = get(_mutex);
     437                if (_lock->owner != NULL){
     438                        return EBUSY;
     439                }
     440                destroy(_mutex);
     441                return 0;
     442        }   //pthread_mutex_destroy_
     443
     444        int pthread_mutex_lock(pthread_mutex_t *_mutex) libcfa_public __THROW {
     445                check_nonnull(_mutex);
     446                mutex_check(_mutex);
     447                simple_owner_lock* _lock = get(_mutex);
     448                lock(*_lock);
     449                return 0;
     450        }   //pthread_mutex_lock_
     451
     452        int pthread_mutex_unlock(pthread_mutex_t *_mutex) libcfa_public __THROW {
     453                check_nonnull(_mutex);
     454                simple_owner_lock* _lock = get(_mutex);
     455                if (_lock->owner != active_thread()){
     456                        return EPERM;
     457                } // current thread does not hold the mutex
     458                unlock(*_lock);
     459                return 0;
     460        }   //pthread_mutex_unlock_
     461
     462        int pthread_mutex_trylock(pthread_mutex_t *_mutex) libcfa_public __THROW {
     463                check_nonnull(_mutex);
     464                simple_owner_lock* _lock = get(_mutex);
     465                if (_lock->owner != active_thread() && _lock->owner != NULL){
     466                        return EBUSY;
     467                }   // if mutex is owned
     468                lock(*_lock);
     469                return 0;
     470        }   //pthread_mutex_trylock_
     471
     472        //######################### Conditional Variable #########################
     473
     474        /* conditional variable routines */
     475        int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) libcfa_public __THROW {
     476                check_nonnull(cond);
     477                init(cond);
     478                return 0;
     479        }  //pthread_cond_init
     480
     481        int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *_mutex) libcfa_public __THROW {
     482                check_nonnull(_mutex);
     483                check_nonnull(cond);
     484                wait(*get(cond), *get(_mutex));
     485                return 0;
     486        } // pthread_cond_wait
     487
     488        int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * _mutex, const struct timespec * abstime) libcfa_public __THROW {
     489                check_nonnull(_mutex);
     490                check_nonnull(cond);
     491                wait(*get(cond), *get(_mutex), *abstime);
     492                return 0;
     493        } // pthread_cond_timedwait
     494
     495        int pthread_cond_signal(pthread_cond_t *cond) libcfa_public __THROW {
     496                check_nonnull(cond);
     497                return notify_one(*get(cond));
     498        } // pthread_cond_signal
     499
     500        int pthread_cond_broadcast(pthread_cond_t *cond) libcfa_public __THROW {
     501                check_nonnull(cond);
     502                return notify_all(*get(cond));
     503        } // pthread_cond_broadcast
     504
     505        int pthread_cond_destroy(pthread_cond_t *cond) libcfa_public __THROW {
     506                check_nonnull(cond);
     507                destroy(cond);
     508                return 0;
     509        } // pthread_cond_destroy
     510
     511
     512
     513        //######################### Local storage #########################
     514
     515        int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) libcfa_public __THROW {
     516                static_assert(sizeof(pthread_once_t) >= sizeof(int),"sizeof(pthread_once_t) < sizeof(int)");
     517                check_nonnull(once_control);
     518                check_nonnull(init_routine);
     519                lock(once_lock);
     520                if ( *((int *)once_control) == 0 ) {
     521                        init_routine();
     522                        *((int *)once_control) = 1;
     523                } // if
     524                unlock(once_lock);
     525                return 0;
     526        } // pthread_once
     527
     528        int pthread_key_create( pthread_key_t *key, void (*destructor)( void * ) ) libcfa_public __THROW {
     529                lock(key_lock);
     530                for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) {
     531                        if ( ! cfa_pthread_keys[i].in_use ) {
     532                                cfa_pthread_keys[i].in_use = true;
     533                                cfa_pthread_keys[i].destructor = destructor;
     534                                unlock( key_lock );
     535                                *key = i;
     536                                return 0;
     537                        } // if
     538                } // for
     539                unlock(key_lock);
     540                return EAGAIN;
     541        }   // pthread_key_create
     542
     543        int pthread_key_delete( pthread_key_t key ) libcfa_public __THROW {
     544                lock(key_lock);
     545                if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) {
     546                        unlock( key_lock );
     547                        return EINVAL;
     548                } // if
     549                cfa_pthread_keys[key].in_use = false;
     550                cfa_pthread_keys[key].destructor = NULL;
     551
     552                // Remove key from all threads with a value.
     553                Pthread_values& p;
     554                Sequence(Pthread_values)& head = cfa_pthread_keys[key].threads;
     555                for ( SeqIter(Pthread_values) iter = { head }; iter | p; ) {
     556                        remove(head, p);
     557                        p.in_use = false;
     558                }
     559                unlock(key_lock);
     560                return 0;
     561        }   // pthread_key_delete
     562
     563        int pthread_setspecific( pthread_key_t key, const void *value ) libcfa_public __THROW {
     564                // get current thread
     565                cfaPthread* t = lookup(pthread_self());
     566                // if current thread's pthreadData is NULL; initialize it
     567                Pthread_values* values;
     568                if (t->pthreadData == NULL){
     569                        values = anew( PTHREAD_KEYS_MAX);
     570                        t->pthreadData = values;
     571                        for (int i = 0;i < PTHREAD_KEYS_MAX; i++){
     572                                t->pthreadData[i].in_use = false;
     573                        }   // for
     574                }   else {
     575                        values = t->pthreadData;
     576                }   // if
     577                // find corresponding key and set value
     578                lock(key_lock);
     579                // if invalid key
     580                if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) {
     581                        unlock( key_lock );
     582                        return EINVAL;
     583                } // if
     584                Pthread_values &entry = values[key];
     585                if ( ! entry.in_use ) {
     586                        entry.in_use = true;
     587                        add(cfa_pthread_keys[key].threads, entry);
     588                } // if
     589                entry.value = (void *)value;
     590                unlock(key_lock);
     591                return 0;
     592        } //pthread_setspecific
     593
     594        void* pthread_getspecific(pthread_key_t key) libcfa_public __THROW {
     595                if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL;
     596
     597                // get current thread
     598                cfaPthread* t = lookup(pthread_self());
     599                if (t->pthreadData == NULL) return NULL;
     600                lock(key_lock);
     601                Pthread_values &entry = ((Pthread_values *)t->pthreadData)[key];
     602                if ( ! entry.in_use ) {
     603                        unlock( key_lock );
     604                        return NULL;
     605                } // if
     606                void *value = entry.value;
     607                unlock(key_lock);
     608
     609                return value;
     610        }   //pthread_get_specific
     611
     612        //######################### Parallelism #########################
     613        void pthread_delete_kernel_threads_() libcfa_public __THROW {   // see uMain::~uMain
     614                Pthread_kernel_threads& p;
     615                for ( StackIter(Pthread_kernel_threads) iter = {cfa_pthreads_kernel_threads}; iter | p; ) {
     616                        delete(&p);
     617                } // for
     618        } // pthread_delete_kernel_threads_
     619
     620        int pthread_getconcurrency( void ) libcfa_public __THROW {      // XOPEN extension
     621                return cfa_pthreads_kernel_threads_zero ? 0 : cfa_pthreads_no_kernel_threads;
     622        } // pthread_getconcurrency
     623
     624        int pthread_setconcurrency( int new_level ) libcfa_public __THROW { // XOPEN extension
     625          if ( new_level < 0 ) return EINVAL;
     626          if ( new_level == 0 ) {
     627                cfa_pthreads_kernel_threads_zero = true;        // remember set to zero, but ignore
     628                return 0;                                       // do not do kernel thread management
     629          } // exit
     630          cfa_pthreads_kernel_threads_zero = false;
     631          lock( concurrency_lock );
     632          for ( ; new_level > cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads += 1 ) { // add processors ?
     633                push(cfa_pthreads_kernel_threads, *new() );
     634          } // for
     635          for ( ; new_level < cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads -= 1 ) { // remove processors ?
     636                delete(&pop(cfa_pthreads_kernel_threads));
     637          } // for
     638          unlock( concurrency_lock );
     639          return 0;
     640        } // pthread_setconcurrency
     641
     642        //######################### Signal #########################
     643
     644
     645         int pthread_sigmask( int /* how */, const sigset_t * /* set */, sigset_t * /* oset */ ) libcfa_public __THROW {
     646                 return 0;
     647         } // pthread_sigmask
     648
     649        int pthread_kill( pthread_t _thread __attribute__(( unused )), int sig ) libcfa_public __THROW {
     650                if ( sig == 0 ) {
     651                        return 0;
     652                } else {
     653                        abort( "pthread_kill : not implemented" );
     654                } // if
     655                return 0;
     656        } // pthread_kill
     657
     658        int pthread_sigqueue(pthread_t , int sig, const union sigval) libcfa_public __THROW {
     659                return 0;
     660        } // pthread_sigqueue
     661
     662        //######################### Scheduling #########################
     663        int pthread_detach( pthread_t threadID ) __THROW {
     664                abort( "pthread_detach" );
     665                return 0;
     666        } // pthread_detach
     667
     668        int pthread_setschedparam( pthread_t /* thread */, int /* policy */, const struct sched_param * /* param */ ) libcfa_public __THROW {
     669                abort( "pthread_setschedparam : not implemented" );
     670                return 0;
     671        } // pthread_setschedparam
     672
     673        int pthread_getschedparam( pthread_t /* thread */, int */* policy */, struct sched_param * /* param */ ) libcfa_public __THROW {
     674                abort( "pthread_getschedparam : not implemented" );
     675                return 0;
     676        } // pthread_getschedparam
     677
     678         //######################### Mutex Attr #########################
     679
     680        int pthread_mutexattr_init( pthread_mutexattr_t * /* attr */ ) libcfa_public __THROW {
     681                return 0;
     682        } // pthread_mutexattr_init
     683
     684        int pthread_mutexattr_destroy( pthread_mutexattr_t * /* attr */ ) libcfa_public __THROW {
     685        return 0;
     686        } // pthread_mutexattr_destroy
     687
     688        int pthread_mutexattr_setpshared( pthread_mutexattr_t * /* attr */, int /* pshared */ ) libcfa_public __THROW {
     689        return 0;
     690        } // pthread_mutexattr_setpshared
     691
     692        int pthread_mutexattr_getpshared( const pthread_mutexattr_t * /* attr */, int * /* pshared */ ) libcfa_public __THROW {
     693        return 0;
     694        } // pthread_mutexattr_getpshared
     695
     696        int pthread_mutexattr_setprotocol( pthread_mutexattr_t * /* attr */, int /* protocol */ ) libcfa_public __THROW {
     697        return 0;
     698        } // pthread_mutexattr_setprotocol
     699
     700        int pthread_mutexattr_getprotocol( const pthread_mutexattr_t * /* attr */, int * /* protocol */ ) libcfa_public __THROW {
     701        return 0;
     702        } // pthread_mutexattr_getprotocol
     703
     704        int pthread_mutexattr_setprioceiling( pthread_mutexattr_t * /* attr */, int /* prioceiling */ ) libcfa_public __THROW {
     705        return 0;
     706        } // pthread_mutexattr_setprioceiling
     707
     708        int pthread_mutexattr_getprioceiling( const pthread_mutexattr_t * /* attr */, int * /* ceiling */ ) libcfa_public __THROW {
     709        return 0;
     710        } // pthread_mutexattr_getprioceiling
     711
     712        int pthread_mutex_setprioceiling( pthread_mutex_t * /* mutex */, int /* prioceiling */, int * /* old_ceiling */ ) libcfa_public __THROW {
     713        return 0;
     714        } // pthread_mutex_setprioceiling
     715
     716        int pthread_mutex_getprioceiling( const pthread_mutex_t * /* mutex */, int * /* ceiling */ ) libcfa_public __THROW {
     717        return 0;
     718        } // pthread_mutex_getprioceiling
     719
     720        int pthread_mutexattr_gettype( __const pthread_mutexattr_t * __restrict /* __attr */, int * __restrict /* __kind */ ) libcfa_public __THROW {
     721        return 0;
     722        } // pthread_mutexattr_gettype
     723
     724        int pthread_mutexattr_settype( pthread_mutexattr_t * /* __attr */, int /* __kind */ ) libcfa_public __THROW {
     725        return 0;
     726        } // pthread_mutexattr_settype
     727
     728        //######################### Mutex #########################
     729
     730        int pthread_mutex_timedlock( pthread_mutex_t *__restrict /* __mutex */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW {
     731                abort( "pthread_mutex_timedlock" );
     732        } // pthread_mutex_timedlock
     733
     734        //######################### Condition #########################
     735
     736        int pthread_condattr_getclock( __const pthread_condattr_t * __restrict /* __attr */, __clockid_t *__restrict /* __clock_id */ ) libcfa_public __THROW {
     737                abort( "pthread_condattr_getclock" );
     738        } // pthread_condattr_getclock
     739
     740        int pthread_condattr_setclock( pthread_condattr_t * /* __attr */, __clockid_t /* __clock_id */ ) libcfa_public __THROW {
     741                abort( "pthread_condattr_setclock" );
     742        } // pthread_condattr_setclock
     743
     744        //######################### Spinlock #########################
     745
     746        int pthread_spin_init( pthread_spinlock_t * /* __lock */, int /*__pshared */ ) libcfa_public __THROW {
     747                abort( "pthread_spin_init" );
     748        } // pthread_spin_init
     749
     750        int pthread_spin_destroy( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
     751                abort( "pthread_spin_destroy" );
     752        } // pthread_spin_destroy
     753
     754        int pthread_spin_lock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
     755                abort( "pthread_spin_lock" );
     756        } // pthread_spin_lock
     757
     758        int pthread_spin_trylock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
     759                abort( "pthread_spin_trylock" );
     760        } // pthread_spin_trylock
     761
     762        int pthread_spin_unlock( pthread_spinlock_t * /* __lock */ ) libcfa_public __THROW {
     763                abort( "pthread_spin_unlock" );
     764        } // pthread_spin_unlock
     765
     766        //######################### Barrier #########################
     767
     768        int pthread_barrier_init( pthread_barrier_t *__restrict /* __barrier */, __const pthread_barrierattr_t *__restrict /* __attr */, unsigned int /* __count */ ) libcfa_public __THROW {
     769                abort( "pthread_barrier_init" );
     770        } // pthread_barrier_init
     771
     772        int pthread_barrier_destroy( pthread_barrier_t * /* __barrier */ ) libcfa_public  __THROW {
     773                abort( "pthread_barrier_destroy" );
     774        } // pthread_barrier_destroy
     775
     776        int pthread_barrier_wait( pthread_barrier_t * /* __barrier */ ) libcfa_public __THROW {
     777                abort( "pthread_barrier_wait" );
     778        } // pthread_barrier_wait
     779
     780        int pthread_barrierattr_init( pthread_barrierattr_t * /* __attr */ ) libcfa_public __THROW {
     781                abort( "pthread_barrierattr_init" );
     782        } // pthread_barrierattr_init
     783
     784        int pthread_barrierattr_destroy( pthread_barrierattr_t * /* __attr */ ) libcfa_public __THROW {
     785                abort( "pthread_barrierattr_destroy" );
     786        } // pthread_barrierattr_destroy
     787
     788        int pthread_barrierattr_getpshared( __const pthread_barrierattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) libcfa_public __THROW {
     789                abort( "pthread_barrierattr_getpshared" );
     790        } // pthread_barrierattr_getpshared
     791
     792        int pthread_barrierattr_setpshared( pthread_barrierattr_t * /* __attr */, int /* __pshared */ ) libcfa_public __THROW {
     793                abort( "pthread_barrierattr_setpshared" );
     794        } // pthread_barrierattr_setpshared
     795
     796        //######################### Clock #########################
     797
     798        int pthread_getcpuclockid( pthread_t /* __thread_id */, __clockid_t * /* __clock_id */ ) libcfa_public __THROW {
     799                abort( "pthread_getcpuclockid" );
     800        } // pthread_getcpuclockid
     801
     802        // pthread_atfork()
    826803
    827804// UNIX98
    828805
    829     //######################### Read/Write #########################
    830 
    831     int pthread_rwlock_init( pthread_rwlock_t *__restrict /* __rwlock */, __const pthread_rwlockattr_t *__restrict /* __attr */ ) libcfa_public __THROW {
    832             abort( "pthread_rwlock_init" );
    833     } // pthread_rwlock_init
    834 
    835     int pthread_rwlock_destroy( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
    836             abort( "pthread_rwlock_destroy" );
    837     } // pthread_rwlock_destroy
    838 
    839     int pthread_rwlock_rdlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
    840             abort( "pthread_rwlock_rdlock" );
    841     } // pthread_rwlock_rdlock
    842 
    843     int pthread_rwlock_tryrdlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
    844             abort( "pthread_rwlock_tryrdlock" );
    845     } // pthread_rwlock_tryrdlock
    846 
    847     int pthread_rwlock_wrlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
    848             abort( "pthread_rwlock_wrlock" );
    849     } // pthread_rwlock_wrlock
    850 
    851     int pthread_rwlock_trywrlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
    852             abort( "pthread_rwlock_trywrlock" );
    853     } // pthread_rwlock_trywrlock
    854 
    855     int pthread_rwlock_unlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
    856             abort( "pthread_rwlock_unlock" );
    857     } // pthread_rwlock_unlock
    858 
    859     int pthread_rwlockattr_init( pthread_rwlockattr_t * /* __attr */ ) libcfa_public __THROW {
    860             abort( "pthread_rwlockattr_init" );
    861     } // pthread_rwlockattr_init
    862 
    863     int pthread_rwlockattr_destroy( pthread_rwlockattr_t * /*__attr */ ) libcfa_public __THROW {
    864             abort( "pthread_rwlockattr_destroy" );
    865     } // pthread_rwlockattr_destroy
    866 
    867     int pthread_rwlockattr_getpshared( __const pthread_rwlockattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) libcfa_public __THROW {
    868             abort( "pthread_rwlockattr_getpshared" );
    869     } // pthread_rwlockattr_getpshared
    870 
    871     int pthread_rwlockattr_setpshared( pthread_rwlockattr_t * /* __attr */, int /* __pshared */ ) libcfa_public __THROW {
    872             abort( "pthread_rwlockattr_setpshared" );
    873     } // pthread_rwlockattr_setpshared
    874 
    875     int pthread_rwlockattr_getkind_np( __const pthread_rwlockattr_t * /* __attr */, int * /* __pref */ ) libcfa_public __THROW {
    876             abort( "pthread_rwlockattr_getkind_np" );
    877     } // pthread_rwlockattr_getkind_np
    878 
    879     int pthread_rwlockattr_setkind_np( pthread_rwlockattr_t * /* __attr */, int /* __pref */ ) libcfa_public __THROW {
    880             abort( "pthread_rwlockattr_setkind_np" );
    881     } // pthread_rwlockattr_setkind_np
     806        //######################### Read/Write #########################
     807
     808        int pthread_rwlock_init( pthread_rwlock_t *__restrict /* __rwlock */, __const pthread_rwlockattr_t *__restrict /* __attr */ ) libcfa_public __THROW {
     809                abort( "pthread_rwlock_init" );
     810        } // pthread_rwlock_init
     811
     812        int pthread_rwlock_destroy( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
     813                abort( "pthread_rwlock_destroy" );
     814        } // pthread_rwlock_destroy
     815
     816        int pthread_rwlock_rdlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
     817                abort( "pthread_rwlock_rdlock" );
     818        } // pthread_rwlock_rdlock
     819
     820        int pthread_rwlock_tryrdlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
     821                abort( "pthread_rwlock_tryrdlock" );
     822        } // pthread_rwlock_tryrdlock
     823
     824        int pthread_rwlock_wrlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
     825                abort( "pthread_rwlock_wrlock" );
     826        } // pthread_rwlock_wrlock
     827
     828        int pthread_rwlock_trywrlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
     829                abort( "pthread_rwlock_trywrlock" );
     830        } // pthread_rwlock_trywrlock
     831
     832        int pthread_rwlock_unlock( pthread_rwlock_t * /* __rwlock */ ) libcfa_public __THROW {
     833                abort( "pthread_rwlock_unlock" );
     834        } // pthread_rwlock_unlock
     835
     836        int pthread_rwlockattr_init( pthread_rwlockattr_t * /* __attr */ ) libcfa_public __THROW {
     837                abort( "pthread_rwlockattr_init" );
     838        } // pthread_rwlockattr_init
     839
     840        int pthread_rwlockattr_destroy( pthread_rwlockattr_t * /*__attr */ ) libcfa_public __THROW {
     841                abort( "pthread_rwlockattr_destroy" );
     842        } // pthread_rwlockattr_destroy
     843
     844        int pthread_rwlockattr_getpshared( __const pthread_rwlockattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) libcfa_public __THROW {
     845                abort( "pthread_rwlockattr_getpshared" );
     846        } // pthread_rwlockattr_getpshared
     847
     848        int pthread_rwlockattr_setpshared( pthread_rwlockattr_t * /* __attr */, int /* __pshared */ ) libcfa_public __THROW {
     849                abort( "pthread_rwlockattr_setpshared" );
     850        } // pthread_rwlockattr_setpshared
     851
     852        int pthread_rwlockattr_getkind_np( __const pthread_rwlockattr_t * /* __attr */, int * /* __pref */ ) libcfa_public __THROW {
     853                abort( "pthread_rwlockattr_getkind_np" );
     854        } // pthread_rwlockattr_getkind_np
     855
     856        int pthread_rwlockattr_setkind_np( pthread_rwlockattr_t * /* __attr */, int /* __pref */ ) libcfa_public __THROW {
     857                abort( "pthread_rwlockattr_setkind_np" );
     858        } // pthread_rwlockattr_setkind_np
    882859
    883860// UNIX98 + XOPEN
    884861
    885     int pthread_rwlock_timedrdlock( pthread_rwlock_t *__restrict  /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW {
    886             abort( "pthread_rwlock_timedrdlock" );
    887     } // pthread_rwlock_timedrdlock
    888 
    889     int pthread_rwlock_timedwrlock( pthread_rwlock_t *__restrict  /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW {
    890             abort( "pthread_rwlock_timedwrlock" );
    891     } // pthread_rwlock_timedwrlock
     862        int pthread_rwlock_timedrdlock( pthread_rwlock_t *__restrict  /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW {
     863                abort( "pthread_rwlock_timedrdlock" );
     864        } // pthread_rwlock_timedrdlock
     865
     866        int pthread_rwlock_timedwrlock( pthread_rwlock_t *__restrict  /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) libcfa_public __THROW {
     867                abort( "pthread_rwlock_timedwrlock" );
     868        } // pthread_rwlock_timedwrlock
    892869
    893870// GNU
    894871
    895     //######################### Parallelism #########################
    896 
    897     int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    898             abort( "pthread_setaffinity_np" );
    899     } // pthread_setaffinity_np
    900 
    901     int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    902             abort( "pthread_getaffinity_np" );
    903     } // pthread_getaffinity_np
    904 
    905     int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    906             abort( "pthread_attr_setaffinity_np" );
    907     } // pthread_attr_setaffinity_np
    908 
    909     int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
    910             abort( "pthread_attr_getaffinity_np" );
    911     } // pthread_attr_getaffinity_np
    912 
    913     //######################### Cancellation #########################
    914 
    915     void _pthread_cleanup_push_defer( struct _pthread_cleanup_buffer * /* __buffer */, void( * /* __routine */ )( void * ), void * /* __arg */ ) libcfa_public __THROW {
    916             abort( "_pthread_cleanup_push_defer" );
    917     } // _pthread_cleanup_push_defer
    918 
    919     void _pthread_cleanup_pop_restore( struct _pthread_cleanup_buffer * /* __buffer */, int /* __execute */ ) libcfa_public __THROW {
    920             abort( "_pthread_cleanup_pop_restore" );
    921     } // _pthread_cleanup_pop_res
    922 
    923     int pthread_cancel( pthread_t threadID ) libcfa_public __THROW {
    924         abort("pthread cancel not implemented");
    925             return 0;
    926     } // pthread_cancel
    927 
    928     int pthread_setcancelstate( int state, int *oldstate ) libcfa_public __THROW {
    929         abort("pthread_setcancelstate not implemented");
    930             return 0;
    931     } // pthread_setcancelstate
    932 
    933     int pthread_setcanceltype( int type, int *oldtype ) libcfa_public __THROW {
    934         abort("pthread_setcanceltype not implemented");
    935             return 0;
    936     } // pthread_setcanceltype
     872        //######################### Parallelism #########################
     873
     874        int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     875                abort( "pthread_setaffinity_np" );
     876        } // pthread_setaffinity_np
     877
     878        int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     879                abort( "pthread_getaffinity_np" );
     880        } // pthread_getaffinity_np
     881
     882        int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     883                abort( "pthread_attr_setaffinity_np" );
     884        } // pthread_attr_setaffinity_np
     885
     886        int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {
     887                abort( "pthread_attr_getaffinity_np" );
     888        } // pthread_attr_getaffinity_np
     889
     890        //######################### Cancellation #########################
     891
     892        void _pthread_cleanup_push_defer( struct _pthread_cleanup_buffer * /* __buffer */, void( * /* __routine */ )( void * ), void * /* __arg */ ) libcfa_public __THROW {
     893                abort( "_pthread_cleanup_push_defer" );
     894        } // _pthread_cleanup_push_defer
     895
     896        void _pthread_cleanup_pop_restore( struct _pthread_cleanup_buffer * /* __buffer */, int /* __execute */ ) libcfa_public __THROW {
     897                abort( "_pthread_cleanup_pop_restore" );
     898        } // _pthread_cleanup_pop_res
     899
     900        int pthread_cancel( pthread_t threadID ) libcfa_public __THROW {
     901                abort("pthread cancel not implemented");
     902                return 0;
     903        } // pthread_cancel
     904
     905        int pthread_setcancelstate( int state, int *oldstate ) libcfa_public __THROW {
     906                abort("pthread_setcancelstate not implemented");
     907                return 0;
     908        } // pthread_setcancelstate
     909
     910        int pthread_setcanceltype( int type, int *oldtype ) libcfa_public __THROW {
     911                abort("pthread_setcanceltype not implemented");
     912                return 0;
     913        } // pthread_setcanceltype
    937914} // extern "C"
    938915
  • libcfa/src/interpose.cfa

    r95dab9e r9cd5bd2  
    111111        void (* exit)( int ) __attribute__(( __noreturn__ ));
    112112        void (* abort)( void ) __attribute__(( __noreturn__ ));
    113         int (*pthread_create)(pthread_t *_thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
    114         int (*pthread_join)(pthread_t _thread, void **retval);
    115         pthread_t (*pthread_self)(void);
    116         int (*pthread_attr_init)(pthread_attr_t *attr);
    117         int (*pthread_attr_destroy)(pthread_attr_t *attr);
    118         int (*pthread_attr_setstack)( pthread_attr_t *attr, void *stackaddr, size_t stacksize );
    119         int (*pthread_attr_getstacksize)( const pthread_attr_t *attr, size_t *stacksize );
    120         int (*pthread_sigmask)(int how, const sigset_t *set, sigset_t *oldset);
    121         int (*pthread_sigqueue)(pthread_t _thread, int sig, const union sigval value);
    122113} __cabi_libc;
    123114
  • libcfa/src/interpose_thread.cfa

    r95dab9e r9cd5bd2  
    1717#include <stdio.h>
    1818#include <string.h>                                                                             // strlen
     19#include <signal.h>
     20#include <pthread.h>
    1921extern "C" {
    2022#include <dlfcn.h>                                                                              // dlopen, dlsym
Note: See TracChangeset for help on using the changeset viewer.