source: libcfa/src/concurrency/pthread.cfa @ a7d696f

pthread-emulation
Last change on this file since a7d696f was a7d696f, checked in by z277zhu <z277zhu@…>, 4 months ago

added pthread symbol interpose

Signed-off-by: z277zhu <z277zhu@…>

  • Property mode set to 100644
File size: 30.3 KB
Line 
1
2#define __cforall_thread__
3#define _GNU_SOURCE
4
5#include "locks.hfa"
6#include <fstream.hfa>
7#include <pthread.h>
8#include <clib/cfathread.h>
9#include <invoke.h>
10#include <bits/stack.hfa>
11
12#ifdef PNOOUTPUT
13 #define PRINT( stmt )
14#else
15 #define PRINT( stmt ) stmt
16#endif // NOOUTPUT
17
18#pragma GCC diagnostic push
19#pragma GCC diagnostic ignored "-Wnonnull-compare"
20
21/* pthread key, pthread once*/
22static simple_owner_lock once_lock,key_lock,magic_mutex_check, concurrency_lock;
23//######################### Local Storage Helpers #########################
24
25#define PTHREADS_THR_MAX 256
26#define PTHREAD_KEYS_MAX 1024
27struct Pthread_values{
28    inline Seqable;
29    void* value;
30    bool in_use;
31};
32
33
34Pthread_values *& Back( Pthread_values * n ) {
35    return (Pthread_values *)Back( (Seqable *)n );
36}
37Pthread_values *& Next( Pthread_values * n ) {
38    return (Pthread_values *)Next( (Colable *)n );
39}
40
41struct Pthread_keys{
42    bool in_use;
43    void (*destructor)( void * );
44    Sequence(Pthread_values) threads;
45};  // Pthread keys
46
47static void ?{}(Pthread_keys& k){
48    //sout | "inited";
49    k.threads{};
50}
51
52// Create storage separately to ensure no constructors are called.
53//static char cfa_pthread_keys_storage[sizeof(Pthread_keys) * PTHREAD_KEYS_MAX] __attribute__((aligned (16))) = {0};
54static Pthread_keys cfa_pthread_keys_storage[PTHREAD_KEYS_MAX] __attribute__((aligned (16)));
55
56void init_pthread_storage(){
57    for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
58        cfa_pthread_keys_storage[i]{};
59    }
60}
61
62#define cfa_pthread_keys ((Pthread_keys *)cfa_pthread_keys_storage)
63
64/* Controlling the iterations of destructors for thread-specific data.  */
65#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS     4
66/* Number of iterations this implementation does.  */
67#define PTHREAD_DESTRUCTOR_ITERATIONS   _POSIX_THREAD_DESTRUCTOR_ITERATIONS
68
69//######################### Parallelism Helpers #########################
70
71struct Pthread_kernel_threads{
72    inline Colable;
73    processor p;
74};
75
76Pthread_kernel_threads *& Next( Pthread_kernel_threads * n ) {
77    return (Pthread_kernel_threads *)Next( (Colable *)n );
78}
79
80static Stack(Pthread_kernel_threads) cfa_pthreads_kernel_threads;
81static bool cfa_pthreads_kernel_threads_zero = false;   // set to zero ?
82static int cfa_pthreads_no_kernel_threads = 1;  // number of kernel threads
83
84
85//######################### Cond Helpers #########################
86
87typedef pthread_cond_var(simple_owner_lock) cfa2pthr_cond_var_t;
88
89/* condvar helper routines */
90static void init(pthread_cond_t* pcond){
91    cfa2pthr_cond_var_t* _cond = (cfa2pthr_cond_var_t*)pcond;
92    ?{}(*_cond);
93}
94
95static cfa2pthr_cond_var_t* get(pthread_cond_t* pcond){
96    return (cfa2pthr_cond_var_t*)pcond;
97}
98
99static void destroy(pthread_cond_t* cond){
100    ^?{}(*get(cond));
101}
102
103
104//######################### Mutex Helper #########################
105
106/* mutex helper routines */
107static void mutex_check(pthread_mutex_t* t){
108        // Use double check to improve performance. Check is safe on x86; volatile prevents compiler reordering
109        volatile pthread_mutex_t *const mutex_ = t;
110        // SKULLDUGGERY: not a portable way to access the kind field, /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
111        int _lock_val = ((pthread_mutex_t *)mutex_)->__data.__lock;
112    //sout | _lock_val ;
113        // kind is a small pthread enumerated type. If it greater than 32, it is a value in an uOwnerlock field.
114        if ( _lock_val == 0 ) {                 // static initialized ?
115            lock(magic_mutex_check);    // race
116            _lock_val = ((pthread_mutex_t *)mutex_)->__data.__lock;
117            if ( _lock_val == 0 ) {             // static initialized ?
118                pthread_mutex_init( t, NULL );
119            } // if
120            unlock(magic_mutex_check);  // race
121        } // if
122} // mutex_check
123
124
125static void init(pthread_mutex_t* plock){
126    simple_owner_lock* _lock = (simple_owner_lock*)plock;
127    ?{}(*_lock);
128}
129
130static simple_owner_lock* get(pthread_mutex_t* plock){
131    return (simple_owner_lock*)plock;
132}
133
134static void destroy(pthread_mutex_t* plock){
135    ^?{}(*get(plock));
136}
137
138//######################### Attr helpers #########################
139struct cfaPthread_attr_t {                                                              // thread attributes
140                int contentionscope;
141                int detachstate;
142                size_t stacksize;
143                void *stackaddr;
144                int policy;
145                int inheritsched;
146                struct sched_param param;
147} typedef cfaPthread_attr_t;
148
149static const cfaPthread_attr_t default_attrs{
150    0,
151    0,
152    (size_t)65000,
153    (void *)NULL,
154    0,
155    0,
156    {0}
157};
158
159
160/*
161cfaPthread_attr_t default_attrs = {
162    PTHREAD_SCOPE_SYSTEM,
163    PTHREAD_CREATE_JOINABLE,
164    (size_t)DEFAULT_STACK_SIZE,
165    (void *)NULL,
166    0,
167    PTHREAD_EXPLICIT_SCHED,
168    {0}
169};
170*/
171
172
173static cfaPthread_attr_t* get(const pthread_attr_t* attr){
174    return (cfaPthread_attr_t*)attr;
175}
176
177
178//######################### Threads Helper #########################
179
180exception pthread_exit_exp {};
181static vtable(pthread_exit_exp) exp;
182
183thread cfaPthread{
184    cfaPthread_attr_t attr;
185    pthread_t pthreadId;
186    void *joinval;                                                                              // pthreads return value
187        pthread_attr_t pthread_attr;                                            // pthread attributes
188    void *(*start_routine)(void *);                     // routine start
189    void *arg;                                                          // thread parameter                           
190    Pthread_values* pthreadData;
191    bool isTerminated;                                  // flag used for tryjoin
192};
193
194/* thread part routines */
195//  cfaPthread entry point
196void main(cfaPthread& _thread) with(_thread){
197    joinval =  start_routine(arg);
198    isTerminated = true;
199}
200
201// generate pthread_t by cfaPthread ptr
202static pthread_t create( cfaPthread *p ) {
203            return (pthread_t)p;
204}
205
206static cfaPthread *lookup( pthread_t p ){
207    return (cfaPthread*)p;
208}
209
210void pthread_deletespecific_( Pthread_values* values )  { // see uMachContext::invokeTask
211    Pthread_values* value;
212    Pthread_keys* key;
213    bool destcalled = true;
214    if (values != NULL){
215        for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) {
216            destcalled = false;
217            lock(key_lock);
218            for (int i = 0; i < PTHREAD_KEYS_MAX; i++){
219                // for each valid key
220                if ( values[i].in_use){
221                    value = &values[i];
222                    key = &cfa_pthread_keys[i];
223                    value->in_use = false;
224                    remove(key->threads, *value);
225                    // if  a  key  value  has  a  non-NULL  destructor pointer,  and  the  thread  has  a  non-NULL  value associated with that key,
226                    // 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.
227                    if (value->value != NULL && key->destructor != NULL){
228                        unlock(key_lock);
229                        key->destructor(value->value); // run destructor
230                        lock(key_lock);
231                        destcalled = true;
232                    }   // if
233                    value->value = NULL;
234                }   // if
235            }   // for
236            unlock(key_lock);
237        }   // for
238        free(values);
239    }   // if
240}
241
242void ^?{}(cfaPthread & mutex t){
243    //^?{}((thread$&)t);
244    Pthread_values* values = t.pthreadData;
245    pthread_deletespecific_(values);
246    PRINT(sout | "thread exited" | t.pthreadId;)
247}
248
249static void ?{}(cfaPthread &t, pthread_t* _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) {
250   
251    // set up user thread stackSize
252    cfaPthread_attr_t * attr = get(_attr);
253    ((thread&)t){ attr ? attr->stacksize: DEFAULT_STACK_SIZE };
254
255    // initialize _thread & cfaPthread id
256    t.pthreadId = create(&t);
257    *_thread = t.pthreadId;
258
259    // if attr null, self attr will be set as default_attrs; else set to attr
260    t.attr = (attr != NULL ? *attr : default_attrs);
261
262    // init start routine and arguments
263    t.start_routine = start_routine;
264    t.arg = arg;
265    t.pthreadData = NULL;
266}   // not used
267
268
269extern "C"{
270    //######################### Pthread Attrs #########################
271
272    int pthread_attr_init(pthread_attr_t *attr){
273        cfaPthread_attr_t* _attr = get(attr);
274        ?{}(*_attr);
275        *_attr = default_attrs;
276        return 0;
277    }
278    int pthread_attr_destroy(pthread_attr_t *attr){
279        ^?{}(*get(attr));
280        return 0;
281    }
282   
283    int pthread_attr_setscope( pthread_attr_t *attr, int contentionscope ) {
284        get( attr )->contentionscope = contentionscope;
285        return 0;
286    } // pthread_attr_setscope
287
288    int pthread_attr_getscope( const pthread_attr_t *attr, int *contentionscope ) {
289        *contentionscope = get( attr )->contentionscope;
290        return 0;
291    } // pthread_attr_getscope
292
293    int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate ) {
294        get( attr )->detachstate = detachstate;
295        return 0;
296    } // pthread_attr_setdetachstate
297
298    int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ) {
299        *detachstate = get( attr )->detachstate;
300        return 0;
301    } // pthread_attr_getdetachstate
302
303    int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ) {
304        get( attr )->stacksize = stacksize;
305        return 0;
306    } // pthread_attr_setstacksize
307
308    int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ) {
309        *stacksize = get( attr )->stacksize;
310        return 0;
311    } // pthread_attr_getstacksize
312
313    int pthread_attr_getguardsize( const pthread_attr_t * /* attr */, size_t * /* guardsize */ ) {
314            return 0;
315    } // pthread_attr_getguardsize
316
317    int pthread_attr_setguardsize( pthread_attr_t * /* attr */, size_t /* guardsize */ ) {
318            return 0;
319    } // pthread_attr_setguardsize
320
321    int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ) {
322        get( attr )->stackaddr = stackaddr;
323        return 0;
324    } // pthread_attr_setstackaddr
325
326    int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ) {
327        *stackaddr = get( attr )->stackaddr;
328        return 0;
329    } // pthread_attr_getstackaddr
330
331    int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ) {
332        get( attr )->stackaddr = stackaddr;
333        get( attr )->stacksize = stacksize;
334            return 0;
335    } // pthread_attr_setstack
336
337    int pthread_attr_getstack( const pthread_attr_t *attr, void **stackaddr, size_t *stacksize ) {
338        *stackaddr = get( attr )->stackaddr;
339        *stacksize = get( attr )->stacksize;
340        return 0;
341    } // pthread_attr_getstack
342
343    // Initialize thread attribute *attr with attributes corresponding to the
344    // already running thread threadID. It shall be called on unitialized attr
345    // and destroyed with pthread_attr_destroy when no longer needed.
346    int pthread_getattr_np( pthread_t threadID, pthread_attr_t *attr ) __THROW { // GNU extension
347        // race condition during copy
348        cfaPthread_attr_t* _attr = get(attr);
349        ?{}(*_attr);
350        if (_attr == NULL){
351            return ENOMEM;
352        }   // if
353        *_attr = lookup( threadID )->attr; // copy all fields
354            return 0;
355    } // pthread_getattr_np
356
357
358    //######################### Threads #########################
359
360    int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg){
361        cfaPthread *t = alloc();
362        (*t){_thread, attr, start_routine, arg};
363        //init_user_pthread(*t, _thread, attr, start_routine, arg);
364        if (t == NULL) return EAGAIN; //no resource
365        return 0;
366    }   //pthread_create_
367
368
369    int pthread_join(pthread_t _thread, void **value_ptr){
370        if (_thread == NULL) return EINVAL;   // if thread is invalid
371        if (_thread == pthread_self()) return EDEADLK;
372        cfaPthread* p = lookup(_thread);    // get user thr pointer   
373        try {
374            join(*p);
375        } catchResume (ThreadCancelled(cfaPthread) * cancel) {} // if thread called pthread_exit
376        if (value_ptr != NULL ) *value_ptr = p->joinval;   // fetch result
377        delete(p);
378        return 0;
379    }   //pthread_join_
380
381    int pthread_tryjoin_np(pthread_t _thread, void **value_ptr){
382        if (_thread == NULL) return EINVAL;  // if thread is invalid
383        if (_thread == pthread_self()) return EDEADLK;
384        cfaPthread* p = lookup(_thread);
385        if (!p->isTerminated) return EBUSY; // thread not finished ?
386        join( *p );
387        if (value_ptr != NULL ) *value_ptr = p->joinval;
388        delete(p);
389        return 0;
390    }   //pthread_join_
391
392    pthread_t pthread_self(void){
393        return (pthread_t)((char*)active_thread()-(sizeof(cfaPthread)-sizeof(thread$)));
394    }   //pthread_self_
395
396    void pthread_exit(void * status){
397        pthread_t pid = pthread_self();
398        cfaPthread* _thread = (cfaPthread*)pid;
399        _thread->joinval = status;  // set return value
400        _thread->isTerminated = 1;  // set terminated flag
401        cancel_stack((pthread_exit_exp){&exp});
402    }   //pthread_exit_
403
404
405
406    //######################### Mutex #########################
407
408    int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t *attr){
409        if (_mutex == NULL) return EINVAL;
410
411        init(_mutex);
412        return 0;
413    }   //pthread_mutex_init_
414
415
416    int pthread_mutex_destroy(pthread_mutex_t *_mutex){
417        if (_mutex == NULL){
418             return EINVAL;
419        }   // if mutex invalid
420        simple_owner_lock* _lock = get(_mutex);
421        if (_lock->owner != NULL){
422            return EBUSY;
423        }
424        destroy(_mutex);
425        return 0;
426    }   //pthread_mutex_destroy_
427
428    int pthread_mutex_lock(pthread_mutex_t *_mutex){
429        if (_mutex == NULL) {
430            return EINVAL;
431        }   // if mutex invalid
432        mutex_check(_mutex);
433        simple_owner_lock* _lock = get(_mutex);
434        lock(*_lock);
435        return 0;
436    }   //pthread_mutex_lock_
437
438    int pthread_mutex_unlock(pthread_mutex_t *_mutex){
439        if (_mutex == NULL) {
440            return EINVAL;
441        } // invalid mutex
442        simple_owner_lock* _lock = get(_mutex);
443        if (_lock->owner != active_thread()){
444            return EPERM;
445        } // current thread does not hold the mutex
446        unlock(*_lock);
447        return 0;
448    }   //pthread_mutex_unlock_
449
450    int pthread_mutex_trylock(pthread_mutex_t *_mutex){
451        if (_mutex == NULL) {
452            return EINVAL;
453        }   // if mutex invalid
454        simple_owner_lock* _lock = get(_mutex);
455        if (_lock->owner != active_thread() && _lock->owner != NULL){
456            return EBUSY;
457        }   // if mutex is owned
458        lock(*_lock);
459        return 0;
460    }   //pthread_mutex_trylock_
461
462    //######################### Conditional Variable #########################
463
464    /* conditional variable routines */
465    int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr){
466        if (cond == NULL) return EINVAL;
467        init(cond);
468        return 0;
469    }
470    int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *_mutex){
471        if (cond == NULL || _mutex == NULL){
472            return EINVAL;
473        }   // invalid cond
474        wait(*get(cond), *get(_mutex));
475        return 0;
476    }
477
478    int pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * _mutex, const struct timespec * abstime){
479        if (cond == NULL || _mutex == NULL){
480            return EINVAL;
481        }   // invalid cond
482        wait(*get(cond), *get(_mutex), *abstime);
483        return 0;
484    }
485
486
487    int pthread_cond_signal(pthread_cond_t *cond){
488        if (cond == NULL){
489            return EINVAL;
490        }   // invalid cond
491        return notify_one(*get(cond));
492    }
493    int pthread_cond_broadcast(pthread_cond_t *cond){
494        if (cond == NULL){
495            return EINVAL;
496        }   // invalid cond
497        return notify_all(*get(cond));
498    }
499    int pthread_cond_destroy(pthread_cond_t *cond){
500        if (cond == NULL){
501            return EINVAL;
502        }   // invalid cond
503        destroy(cond);
504        return 0;
505    }
506
507
508
509    //######################### Local storage #########################
510
511    int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)){
512        lock(once_lock);
513        if ( *((int *)once_control) == 0 ) {
514            init_routine();
515            *((int *)once_control) = 1;
516            } // if
517        unlock(once_lock);
518        return 0;
519    }
520
521    int pthread_key_create( pthread_key_t *key, void (*destructor)( void * ) ){
522        lock(key_lock);
523        for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) {
524            if ( ! cfa_pthread_keys[i].in_use ) {
525                cfa_pthread_keys[i].in_use = true;
526                cfa_pthread_keys[i].destructor = destructor;
527                unlock( key_lock );
528                *key = i;
529                return 0;
530            } // if
531        } // for
532        unlock(key_lock);
533        return EAGAIN;
534    }   // pthread_key_create
535
536    int pthread_key_delete( pthread_key_t key ){
537        lock(key_lock);
538        if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) {
539            unlock( key_lock );
540            return EINVAL;
541        } // if
542        cfa_pthread_keys[key].in_use = false;
543        cfa_pthread_keys[key].destructor = NULL;
544
545        // Remove key from all threads with a value.
546        Pthread_values& p;
547        Sequence(Pthread_values)& head = cfa_pthread_keys[key].threads;
548        for ( SeqIter(Pthread_values) iter = { head }; iter | p; ) {
549            remove(head, p);
550            p.in_use = false;
551        }
552        unlock(key_lock);
553        return 0;
554    }   // pthread_key_delete
555
556    int pthread_setspecific( pthread_key_t key, const void *value ){
557        // get current thread
558        cfaPthread* t = lookup(pthread_self());
559        // if current thread's pthreadData is NULL; initialize it
560        Pthread_values* values;
561        if (t->pthreadData == NULL){
562            values = anew( PTHREAD_KEYS_MAX);
563            t->pthreadData = values;
564            for (int i = 0;i < PTHREAD_KEYS_MAX; i++){
565                t->pthreadData[i].in_use = false;
566            }   // for
567        }   else {
568            values = t->pthreadData;
569        }   // if
570        // find corresponding key and set value
571        lock(key_lock);
572        // if invalid key
573        if ( key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use ) {
574            unlock( key_lock );
575            return EINVAL;
576        } // if
577        Pthread_values &entry = values[key];
578        if ( ! entry.in_use ) {
579            entry.in_use = true;
580            add(cfa_pthread_keys[key].threads, entry);
581        } // if
582        entry.value = (void *)value;
583        unlock(key_lock);
584        return 0;
585    } //pthread_setspecific
586
587    void* pthread_getspecific(pthread_key_t key){
588        if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL;
589
590        // get current thread
591        cfaPthread* t = lookup(pthread_self());
592        if (t->pthreadData == NULL) return NULL;
593        lock(key_lock);
594        Pthread_values &entry = ((Pthread_values *)t->pthreadData)[key];
595        if ( ! entry.in_use ) {
596            unlock( key_lock );
597            return NULL;
598        } // if
599            void *value = entry.value;
600        unlock(key_lock);
601
602        return value;
603    }   //pthread_get_specific
604
605    //######################### Parallelism #########################
606    void pthread_delete_kernel_threads_() {     // see uMain::~uMain
607        Pthread_kernel_threads& p;
608        for ( StackIter(Pthread_kernel_threads) iter = {cfa_pthreads_kernel_threads}; iter | p; ) {
609            delete(&p);
610        } // for
611    } // pthread_delete_kernel_threads_
612
613    int pthread_getconcurrency( void ) {        // XOPEN extension
614            return cfa_pthreads_kernel_threads_zero ? 0 : cfa_pthreads_no_kernel_threads;
615    } // pthread_getconcurrency
616
617    int pthread_setconcurrency( int new_level ) { // XOPEN extension
618      if ( new_level < 0 ) return EINVAL;
619      if ( new_level == 0 ) {
620        cfa_pthreads_kernel_threads_zero = true;        // remember set to zero, but ignore
621        return 0;                                       // do not do kernel thread management
622      } // exit
623      cfa_pthreads_kernel_threads_zero = false;
624      lock( concurrency_lock );
625      for ( ; new_level > cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads += 1 ) { // add processors ?
626        push(cfa_pthreads_kernel_threads, *new() );
627      } // for
628      for ( ; new_level < cfa_pthreads_no_kernel_threads; cfa_pthreads_no_kernel_threads -= 1 ) { // remove processors ?
629        delete(&pop(cfa_pthreads_kernel_threads));
630      } // for
631      unlock( concurrency_lock );
632      return 0;
633    } // pthread_setconcurrency
634
635    //######################### Scheduling #########################
636
637
638    int pthread_setschedparam( pthread_t /* thread */, int /* policy */, const struct sched_param * /* param */ ) __THROW {
639        abort( "pthread_setschedparam : not implemented" );
640        return 0;
641    } // pthread_setschedparam
642
643    int pthread_getschedparam( pthread_t /* thread */, int */* policy */, struct sched_param * /* param */ ) __THROW {
644        abort( "pthread_getschedparam : not implemented" );
645        return 0;
646    } // pthread_getschedparam
647
648     //######################### Mutex Attr #########################
649
650    int pthread_mutexattr_init( pthread_mutexattr_t * /* attr */ ) __THROW {
651        return 0;
652    } // pthread_mutexattr_init
653
654    int pthread_mutexattr_destroy( pthread_mutexattr_t * /* attr */ ) __THROW {
655        return 0;
656    } // pthread_mutexattr_destroy
657
658    int pthread_mutexattr_setpshared( pthread_mutexattr_t * /* attr */, int /* pshared */ ) __THROW {
659        return 0;
660    } // pthread_mutexattr_setpshared
661
662    int pthread_mutexattr_getpshared( const pthread_mutexattr_t * /* attr */, int * /* pshared */ ) __THROW {
663        return 0;
664    } // pthread_mutexattr_getpshared
665
666    int pthread_mutexattr_setprotocol( pthread_mutexattr_t * /* attr */, int /* protocol */ ) __THROW {
667        return 0;
668    } // pthread_mutexattr_setprotocol
669
670    int pthread_mutexattr_getprotocol( const pthread_mutexattr_t * /* attr */, int * /* protocol */ ) __THROW {
671        return 0;
672    } // pthread_mutexattr_getprotocol
673
674    int pthread_mutexattr_setprioceiling( pthread_mutexattr_t * /* attr */, int /* prioceiling */ ) __THROW {
675        return 0;
676    } // pthread_mutexattr_setprioceiling
677
678    int pthread_mutexattr_getprioceiling( const pthread_mutexattr_t * /* attr */, int * /* ceiling */ ) __THROW {
679        return 0;
680    } // pthread_mutexattr_getprioceiling
681
682    int pthread_mutex_setprioceiling( pthread_mutex_t * /* mutex */, int /* prioceiling */, int * /* old_ceiling */ ) __THROW {
683        return 0;
684    } // pthread_mutex_setprioceiling
685
686    int pthread_mutex_getprioceiling( const pthread_mutex_t * /* mutex */, int * /* ceiling */ ) __THROW {
687        return 0;
688    } // pthread_mutex_getprioceiling
689
690    int pthread_mutexattr_gettype( __const pthread_mutexattr_t * __restrict /* __attr */, int * __restrict /* __kind */ ) __THROW {
691        return 0;
692    } // pthread_mutexattr_gettype
693
694    int pthread_mutexattr_settype( pthread_mutexattr_t * /* __attr */, int /* __kind */ ) __THROW {
695        return 0;
696    } // pthread_mutexattr_settype
697
698    //######################### Mutex #########################
699
700    int pthread_mutex_timedlock( pthread_mutex_t *__restrict /* __mutex */, __const struct timespec *__restrict /* __abstime */ ) __THROW {
701            abort( "pthread_mutex_timedlock" );
702    } // pthread_mutex_timedlock
703
704    //######################### Condition #########################
705
706    int pthread_condattr_getclock( __const pthread_condattr_t * __restrict /* __attr */, __clockid_t *__restrict /* __clock_id */ ) __THROW {
707            abort( "pthread_condattr_getclock" );
708    } // pthread_condattr_getclock
709
710    int pthread_condattr_setclock( pthread_condattr_t * /* __attr */, __clockid_t /* __clock_id */ ) __THROW {
711            abort( "pthread_condattr_setclock" );
712    } // pthread_condattr_setclock
713
714    //######################### Spinlock #########################
715
716    int pthread_spin_init( pthread_spinlock_t * /* __lock */, int /*__pshared */ ) __THROW {
717            abort( "pthread_spin_init" );
718    } // pthread_spin_init
719
720    int pthread_spin_destroy( pthread_spinlock_t * /* __lock */ ) __THROW {
721            abort( "pthread_spin_destroy" );
722    } // pthread_spin_destroy
723
724    int pthread_spin_lock( pthread_spinlock_t * /* __lock */ ) __THROW {
725            abort( "pthread_spin_lock" );
726    } // pthread_spin_lock
727
728    int pthread_spin_trylock( pthread_spinlock_t * /* __lock */ ) __THROW {
729            abort( "pthread_spin_trylock" );
730    } // pthread_spin_trylock
731
732    int pthread_spin_unlock( pthread_spinlock_t * /* __lock */ ) __THROW {
733            abort( "pthread_spin_unlock" );
734    } // pthread_spin_unlock
735
736    //######################### Barrier #########################
737
738    int pthread_barrier_init( pthread_barrier_t *__restrict /* __barrier */, __const pthread_barrierattr_t *__restrict /* __attr */, unsigned int /* __count */ ) __THROW {
739            abort( "pthread_barrier_init" );
740    } // pthread_barrier_init
741
742    int pthread_barrier_destroy( pthread_barrier_t * /* __barrier */ ) __THROW {
743            abort( "pthread_barrier_destroy" );
744    } // pthread_barrier_destroy
745
746    int pthread_barrier_wait( pthread_barrier_t * /* __barrier */ ) __THROW {
747            abort( "pthread_barrier_wait" );
748    } // pthread_barrier_wait
749
750    int pthread_barrierattr_init( pthread_barrierattr_t * /* __attr */ ) __THROW {
751            abort( "pthread_barrierattr_init" );
752    } // pthread_barrierattr_init
753
754    int pthread_barrierattr_destroy( pthread_barrierattr_t * /* __attr */ ) __THROW {
755            abort( "pthread_barrierattr_destroy" );
756    } // pthread_barrierattr_destroy
757
758    int pthread_barrierattr_getpshared( __const pthread_barrierattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) __THROW {
759            abort( "pthread_barrierattr_getpshared" );
760    } // pthread_barrierattr_getpshared
761
762    int pthread_barrierattr_setpshared( pthread_barrierattr_t * /* __attr */, int /* __pshared */ ) __THROW {
763            abort( "pthread_barrierattr_setpshared" );
764    } // pthread_barrierattr_setpshared
765
766    //######################### Clock #########################
767
768    int pthread_getcpuclockid( pthread_t /* __thread_id */, __clockid_t * /* __clock_id */ ) __THROW {
769            abort( "pthread_getcpuclockid" );
770    } // pthread_getcpuclockid
771
772    // pthread_atfork()
773
774// UNIX98
775
776    //######################### Read/Write #########################
777
778    int pthread_rwlock_init( pthread_rwlock_t *__restrict /* __rwlock */, __const pthread_rwlockattr_t *__restrict /* __attr */ ) __THROW {
779            abort( "pthread_rwlock_init" );
780    } // pthread_rwlock_init
781
782    int pthread_rwlock_destroy( pthread_rwlock_t * /* __rwlock */ ) __THROW {
783            abort( "pthread_rwlock_destroy" );
784    } // pthread_rwlock_destroy
785
786    int pthread_rwlock_rdlock( pthread_rwlock_t * /* __rwlock */ ) __THROW {
787            abort( "pthread_rwlock_rdlock" );
788    } // pthread_rwlock_rdlock
789
790    int pthread_rwlock_tryrdlock( pthread_rwlock_t * /* __rwlock */ ) __THROW {
791            abort( "pthread_rwlock_tryrdlock" );
792    } // pthread_rwlock_tryrdlock
793
794    int pthread_rwlock_wrlock( pthread_rwlock_t * /* __rwlock */ ) __THROW {
795            abort( "pthread_rwlock_wrlock" );
796    } // pthread_rwlock_wrlock
797
798    int pthread_rwlock_trywrlock( pthread_rwlock_t * /* __rwlock */ ) __THROW {
799            abort( "pthread_rwlock_trywrlock" );
800    } // pthread_rwlock_trywrlock
801
802    int pthread_rwlock_unlock( pthread_rwlock_t * /* __rwlock */ ) __THROW {
803            abort( "pthread_rwlock_unlock" );
804    } // pthread_rwlock_unlock
805
806    int pthread_rwlockattr_init( pthread_rwlockattr_t * /* __attr */ ) __THROW {
807            abort( "pthread_rwlockattr_init" );
808    } // pthread_rwlockattr_init
809
810    int pthread_rwlockattr_destroy( pthread_rwlockattr_t * /*__attr */ ) __THROW {
811            abort( "pthread_rwlockattr_destroy" );
812    } // pthread_rwlockattr_destroy
813
814    int pthread_rwlockattr_getpshared( __const pthread_rwlockattr_t * __restrict /* __attr */, int *__restrict /* __pshared */ ) __THROW {
815            abort( "pthread_rwlockattr_getpshared" );
816    } // pthread_rwlockattr_getpshared
817
818    int pthread_rwlockattr_setpshared( pthread_rwlockattr_t * /* __attr */, int /* __pshared */ ) __THROW {
819            abort( "pthread_rwlockattr_setpshared" );
820    } // pthread_rwlockattr_setpshared
821
822    int pthread_rwlockattr_getkind_np( __const pthread_rwlockattr_t * /* __attr */, int * /* __pref */ ) __THROW {
823            abort( "pthread_rwlockattr_getkind_np" );
824    } // pthread_rwlockattr_getkind_np
825
826    int pthread_rwlockattr_setkind_np( pthread_rwlockattr_t * /* __attr */, int /* __pref */ ) __THROW {
827            abort( "pthread_rwlockattr_setkind_np" );
828    } // pthread_rwlockattr_setkind_np
829
830// UNIX98 + XOPEN
831
832    int pthread_rwlock_timedrdlock( pthread_rwlock_t *__restrict  /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) __THROW {
833            abort( "pthread_rwlock_timedrdlock" );
834    } // pthread_rwlock_timedrdlock
835
836    int pthread_rwlock_timedwrlock( pthread_rwlock_t *__restrict  /* __rwlock */, __const struct timespec *__restrict /* __abstime */ ) __THROW {
837            abort( "pthread_rwlock_timedwrlock" );
838    } // pthread_rwlock_timedwrlock
839
840// GNU
841
842    //######################### Parallelism #########################
843
844    int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) __THROW {
845            abort( "pthread_setaffinity_np" );
846    } // pthread_setaffinity_np
847
848    int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) __THROW {
849            abort( "pthread_getaffinity_np" );
850    } // pthread_getaffinity_np
851
852    int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) __THROW {
853            abort( "pthread_attr_setaffinity_np" );
854    } // pthread_attr_setaffinity_np
855
856    int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) __THROW {
857            abort( "pthread_attr_getaffinity_np" );
858    } // pthread_attr_getaffinity_np
859
860    //######################### Cancellation #########################
861
862    void _pthread_cleanup_push_defer( struct _pthread_cleanup_buffer * /* __buffer */, void( * /* __routine */ )( void * ), void * /* __arg */ ) __THROW {
863            abort( "_pthread_cleanup_push_defer" );
864    } // _pthread_cleanup_push_defer
865
866    void _pthread_cleanup_pop_restore( struct _pthread_cleanup_buffer * /* __buffer */, int /* __execute */ ) __THROW {
867            abort( "_pthread_cleanup_pop_restore" );
868    } // _pthread_cleanup_pop_res
869
870    int pthread_cancel( pthread_t threadID ) __THROW {
871        abort("pthread cancel not implemented");
872            return 0;
873    } // pthread_cancel
874
875    int pthread_setcancelstate( int state, int *oldstate ) __THROW {
876        abort("pthread_setcancelstate not implemented");
877            return 0;
878    } // pthread_setcancelstate
879
880    int pthread_setcanceltype( int type, int *oldtype ) __THROW {
881        abort("pthread_setcanceltype not implemented");
882            return 0;
883    } // pthread_setcanceltype
884}
885#pragma GCC diagnostic pop
886
Note: See TracBrowser for help on using the repository browser.