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