source: libcfa/src/concurrency/pthread.cfa@ 9cbb2d4

Last change on this file since 9cbb2d4 was 9cbb2d4, checked in by Peter A. Buhr <pabuhr@…>, 3 days ago

remove enum for PTHREAD_KEYS_MAX and replace with #include <limits.h>

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