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

ADT ast-experimental
Last change on this file since ccf1d99 was 8bd886e, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Some clean-up in pthread emulation

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