Changeset 3494ca9 for libcfa/src
- Timestamp:
- Feb 19, 2023, 5:39:56 PM (22 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- c910709
- Parents:
- ed52dd5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/pthread.cfa
red52dd5 r3494ca9 50 50 struct pthread_keys { 51 51 bool in_use; 52 void (* destructor)( void * );52 void (* destructor)( void * ); 53 53 Sequence(pthread_values) threads; 54 54 }; … … 62 62 63 63 static void init_pthread_storage() { 64 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ) {64 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ) { 65 65 cfa_pthread_keys_storage[i]{}; 66 66 } … … 97 97 static void init(pthread_cond_t * pcond) { 98 98 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 99 cfa2pthr_cond_var_t * _cond = (cfa2pthr_cond_var_t *)pcond;99 cfa2pthr_cond_var_t * _cond = (cfa2pthr_cond_var_t *)pcond; 100 100 ?{}(*_cond); 101 101 } … … 103 103 static cfa2pthr_cond_var_t * get(pthread_cond_t * pcond) { 104 104 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 105 return (cfa2pthr_cond_var_t *)pcond;106 } 107 108 static void destroy(pthread_cond_t * cond) {105 return (cfa2pthr_cond_var_t *)pcond; 106 } 107 108 static void destroy(pthread_cond_t * cond) { 109 109 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 110 110 ^?{}(*get(cond)); … … 115 115 116 116 /* mutex helper routines */ 117 static void mutex_check(pthread_mutex_t * t) {117 static void mutex_check(pthread_mutex_t * t) { 118 118 // Use double check to improve performance. 119 119 // Check is safe on x86; volatile prevents compiler reordering 120 volatile pthread_mutex_t * const mutex_ = t;120 volatile pthread_mutex_t * const mutex_ = t; 121 121 122 122 // SKULLDUGGERY: not a portable way to access the kind field, /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h … … 135 135 136 136 137 static void init(pthread_mutex_t * plock) {137 static void init(pthread_mutex_t * plock) { 138 138 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 139 simple_owner_lock * _lock = (simple_owner_lock*)plock;139 simple_owner_lock * _lock = (simple_owner_lock *)plock; 140 140 ?{}(*_lock); 141 141 } 142 142 143 static simple_owner_lock * get(pthread_mutex_t* plock) {143 static simple_owner_lock * get(pthread_mutex_t * plock) { 144 144 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 145 return (simple_owner_lock *)plock;146 } 147 148 static void destroy(pthread_mutex_t * plock) {145 return (simple_owner_lock *)plock; 146 } 147 148 static void destroy(pthread_mutex_t * plock) { 149 149 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 150 150 ^?{}(*get(plock)); … … 156 156 int detachstate; 157 157 size_t stacksize; 158 void * stackaddr;158 void * stackaddr; 159 159 int policy; 160 160 int inheritsched; … … 162 162 } typedef cfaPthread_attr_t; 163 163 164 static const cfaPthread_attr_t default_attrs {164 static const cfaPthread_attr_t default_attrs { 165 165 0, 166 166 0, 167 (size_t)65000,168 (void *)NULL,167 65_000, 168 NULL, 169 169 0, 170 170 0, … … 172 172 }; 173 173 174 static cfaPthread_attr_t * get(const pthread_attr_t* attr) {175 static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t), "sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)");176 return (cfaPthread_attr_t *)attr;174 static cfaPthread_attr_t * get(const pthread_attr_t * attr) { 175 static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t), "sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)"); 176 return (cfaPthread_attr_t *)attr; 177 177 } 178 178 … … 189 189 190 190 // pthreads return value 191 void * joinval;191 void * joinval; 192 192 193 193 // pthread attributes 194 194 pthread_attr_t pthread_attr; 195 195 196 void *(* start_routine)(void *);197 void * start_arg;196 void *(* start_routine)(void *); 197 void * start_arg; 198 198 199 199 // thread local data 200 pthread_values * pthreadData;200 pthread_values * pthreadData; 201 201 202 202 // flag used for tryjoin … … 206 206 /* thread part routines */ 207 207 // cfaPthread entry point 208 void main( cfaPthread & _thread ) with( _thread) {209 joinval = start_routine( start_arg);208 void main(cfaPthread & _thread) with(_thread) { 209 joinval = start_routine(start_arg); 210 210 isTerminated = true; 211 211 } 212 212 213 213 static cfaPthread * lookup( pthread_t p ) { 214 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *),"sizeof(pthread_t) < sizeof(cfaPthread*)");215 return (cfaPthread *)p;216 } 217 218 static void pthread_deletespecific_( pthread_values * values ) { // see uMachContext::invokeTask219 pthread_values * value;220 pthread_keys * key;214 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *),"sizeof(pthread_t) < sizeof(cfaPthread *)"); 215 return (cfaPthread *)p; 216 } 217 218 static void pthread_deletespecific_( pthread_values * values ) { // see uMachContext::invokeTask 219 pthread_values * value; 220 pthread_keys * key; 221 221 bool destcalled = true; 222 222 if (values != NULL) { … … 224 224 destcalled = false; 225 225 lock(key_lock); 226 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ) {226 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++ ) { 227 227 // for each valid key 228 228 if ( values[i].in_use) { … … 254 254 } 255 255 256 static void ?{}(cfaPthread & t, pthread_t* _thread, const pthread_attr_t * _attr,void *(*start_routine)(void *), void * arg) {257 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread*)");256 static void ?{}(cfaPthread & t, pthread_t * _thread, const pthread_attr_t * _attr,void *(* start_routine)(void *), void * arg) { 257 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread *), "pthread_t too small to hold a pointer: sizeof(pthread_t) < sizeof(cfaPthread *)"); 258 258 259 259 // set up user thread stackSize 260 260 cfaPthread_attr_t * attr = get(_attr); 261 ((thread&)t) 261 ((thread&)t){ attr ? attr->stacksize: DEFAULT_STACK_SIZE }; 262 262 263 263 // initialize _thread & cfaPthread id … … 277 277 //######################### Pthread Attrs ######################### 278 278 279 int pthread_attr_init(pthread_attr_t * attr) libcfa_public __THROW {280 cfaPthread_attr_t * _attr = get(attr);279 int pthread_attr_init(pthread_attr_t * attr) libcfa_public __THROW { 280 cfaPthread_attr_t * _attr = get(attr); 281 281 ?{}(*_attr, default_attrs); 282 282 return 0; 283 283 } 284 int pthread_attr_destroy(pthread_attr_t * attr) libcfa_public __THROW {284 int pthread_attr_destroy(pthread_attr_t * attr) libcfa_public __THROW { 285 285 ^?{}(*get(attr)); 286 286 return 0; 287 287 } 288 288 289 int pthread_attr_setscope( pthread_attr_t * attr, int contentionscope ) libcfa_public __THROW {289 int pthread_attr_setscope( pthread_attr_t * attr, int contentionscope ) libcfa_public __THROW { 290 290 get( attr )->contentionscope = contentionscope; 291 291 return 0; 292 292 } // pthread_attr_setscope 293 293 294 int pthread_attr_getscope( const pthread_attr_t * attr, int *contentionscope ) libcfa_public __THROW {294 int pthread_attr_getscope( const pthread_attr_t * attr, int * contentionscope ) libcfa_public __THROW { 295 295 *contentionscope = get( attr )->contentionscope; 296 296 return 0; 297 297 } // pthread_attr_getscope 298 298 299 int pthread_attr_setdetachstate( pthread_attr_t * attr, int detachstate ) libcfa_public __THROW {299 int pthread_attr_setdetachstate( pthread_attr_t * attr, int detachstate ) libcfa_public __THROW { 300 300 get( attr )->detachstate = detachstate; 301 301 return 0; 302 302 } // pthread_attr_setdetachstate 303 303 304 int pthread_attr_getdetachstate( const pthread_attr_t * attr, int *detachstate ) libcfa_public __THROW {304 int pthread_attr_getdetachstate( const pthread_attr_t * attr, int * detachstate ) libcfa_public __THROW { 305 305 *detachstate = get( attr )->detachstate; 306 306 return 0; 307 307 } // pthread_attr_getdetachstate 308 308 309 int pthread_attr_setstacksize( pthread_attr_t * attr, size_t stacksize ) libcfa_public __THROW {309 int pthread_attr_setstacksize( pthread_attr_t * attr, size_t stacksize ) libcfa_public __THROW { 310 310 get( attr )->stacksize = stacksize; 311 311 return 0; 312 312 } // pthread_attr_setstacksize 313 313 314 int pthread_attr_getstacksize( const pthread_attr_t * attr, size_t *stacksize ) libcfa_public __THROW {314 int pthread_attr_getstacksize( const pthread_attr_t * attr, size_t * stacksize ) libcfa_public __THROW { 315 315 *stacksize = get( attr )->stacksize; 316 316 return 0; … … 325 325 } // pthread_attr_setguardsize 326 326 327 int pthread_attr_setstackaddr( pthread_attr_t * attr, void *stackaddr ) libcfa_public __THROW {327 int pthread_attr_setstackaddr( pthread_attr_t * attr, void * stackaddr ) libcfa_public __THROW { 328 328 get( attr )->stackaddr = stackaddr; 329 329 return 0; 330 330 } // pthread_attr_setstackaddr 331 331 332 int pthread_attr_getstackaddr( const pthread_attr_t * attr, void **stackaddr ) libcfa_public __THROW {332 int pthread_attr_getstackaddr( const pthread_attr_t * attr, void ** stackaddr ) libcfa_public __THROW { 333 333 *stackaddr = get( attr )->stackaddr; 334 334 return 0; 335 335 } // pthread_attr_getstackaddr 336 336 337 int pthread_attr_setstack( pthread_attr_t * attr, void *stackaddr, size_t stacksize ) libcfa_public __THROW {337 int pthread_attr_setstack( pthread_attr_t * attr, void * stackaddr, size_t stacksize ) libcfa_public __THROW { 338 338 get( attr )->stackaddr = stackaddr; 339 339 get( attr )->stacksize = stacksize; … … 341 341 } // pthread_attr_setstack 342 342 343 int pthread_attr_getstack( const pthread_attr_t * attr, void **stackaddr, size_t *stacksize ) libcfa_public __THROW {343 int pthread_attr_getstack( const pthread_attr_t * attr, void ** stackaddr, size_t * stacksize ) libcfa_public __THROW { 344 344 *stackaddr = get( attr )->stackaddr; 345 345 *stacksize = get( attr )->stacksize; … … 350 350 // already running thread threadID. It shall be called on unitialized attr 351 351 // and destroyed with pthread_attr_destroy when no longer needed. 352 int pthread_getattr_np( pthread_t threadID, pthread_attr_t * attr ) libcfa_public __THROW { // GNU extension352 int pthread_getattr_np( pthread_t threadID, pthread_attr_t * attr ) libcfa_public __THROW { // GNU extension 353 353 check_nonnull(attr); 354 354 … … 362 362 //######################### Threads ######################### 363 363 364 int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW { 365 cfaPthread *t = alloc(); 366 (*t) {_thread, attr, start_routine, arg}; 367 return 0; 368 } 369 370 371 int pthread_join(pthread_t _thread, void **value_ptr) libcfa_public __THROW { 364 int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(* start_routine)(void *), void * arg) libcfa_public __THROW { 365 cfaPthread * t = alloc(); 366 (*t){_thread, attr, start_routine, arg}; 367 return 0; 368 } 369 370 int pthread_join(pthread_t _thread, void ** value_ptr) libcfa_public __THROW { 372 371 // if thread is invalid 373 372 if (_thread == NULL) return EINVAL; … … 375 374 376 375 // get user thr pointer 377 cfaPthread * p = lookup(_thread);376 cfaPthread * p = lookup(_thread); 378 377 try { 379 378 join(*p); … … 388 387 } 389 388 390 int pthread_tryjoin_np(pthread_t _thread, void ** value_ptr) libcfa_public __THROW {389 int pthread_tryjoin_np(pthread_t _thread, void ** value_ptr) libcfa_public __THROW { 391 390 // if thread is invalid 392 391 if (_thread == NULL) return EINVAL; 393 392 if (_thread == pthread_self()) return EDEADLK; 394 393 395 cfaPthread * p = lookup(_thread);394 cfaPthread * p = lookup(_thread); 396 395 397 396 // thread not finished ? … … 411 410 void pthread_exit(void * status) libcfa_public __THROW { 412 411 pthread_t pid = pthread_self(); 413 cfaPthread * _thread = (cfaPthread*)pid;412 cfaPthread * _thread = (cfaPthread *)pid; 414 413 _thread->joinval = status; // set return value 415 414 _thread->isTerminated = 1; // set terminated flag 416 cancel_stack((pthread_exit_exp) 415 cancel_stack((pthread_exit_exp){&exp_vt}); 417 416 } //pthread_exit_ 418 417 … … 425 424 //######################### Mutex ######################### 426 425 427 int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t * attr) libcfa_public __THROW {426 int pthread_mutex_init(pthread_mutex_t *_mutex, const pthread_mutexattr_t * attr) libcfa_public __THROW { 428 427 check_nonnull(_mutex); 429 428 init(_mutex); … … 434 433 int pthread_mutex_destroy(pthread_mutex_t *_mutex) libcfa_public __THROW { 435 434 check_nonnull(_mutex); 436 simple_owner_lock * _lock = get(_mutex);435 simple_owner_lock * _lock = get(_mutex); 437 436 if (_lock->owner != NULL) { 438 437 return EBUSY; … … 445 444 check_nonnull(_mutex); 446 445 mutex_check(_mutex); 447 simple_owner_lock * _lock = get(_mutex);446 simple_owner_lock * _lock = get(_mutex); 448 447 lock(*_lock); 449 448 return 0; … … 452 451 int pthread_mutex_unlock(pthread_mutex_t *_mutex) libcfa_public __THROW { 453 452 check_nonnull(_mutex); 454 simple_owner_lock * _lock = get(_mutex);453 simple_owner_lock * _lock = get(_mutex); 455 454 if (_lock->owner != active_thread()) { 456 455 return EPERM; … … 462 461 int pthread_mutex_trylock(pthread_mutex_t *_mutex) libcfa_public __THROW { 463 462 check_nonnull(_mutex); 464 simple_owner_lock * _lock = get(_mutex);463 simple_owner_lock * _lock = get(_mutex); 465 464 if (_lock->owner != active_thread() && _lock->owner != NULL) { 466 465 return EBUSY; … … 473 472 474 473 /* conditional variable routines */ 475 int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t *attr) libcfa_public __THROW {474 int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * attr) libcfa_public __THROW { 476 475 check_nonnull(cond); 477 476 init(cond); … … 479 478 } //pthread_cond_init 480 479 481 int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t *_mutex) libcfa_public __THROW {480 int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t *_mutex) libcfa_public __THROW { 482 481 check_nonnull(_mutex); 483 482 check_nonnull(cond); … … 493 492 } // pthread_cond_timedwait 494 493 495 int pthread_cond_signal(pthread_cond_t * cond) libcfa_public __THROW {494 int pthread_cond_signal(pthread_cond_t * cond) libcfa_public __THROW { 496 495 check_nonnull(cond); 497 496 return notify_one(*get(cond)); 498 497 } // pthread_cond_signal 499 498 500 int pthread_cond_broadcast(pthread_cond_t * cond) libcfa_public __THROW {499 int pthread_cond_broadcast(pthread_cond_t * cond) libcfa_public __THROW { 501 500 check_nonnull(cond); 502 501 return notify_all(*get(cond)); 503 502 } // pthread_cond_broadcast 504 503 505 int pthread_cond_destroy(pthread_cond_t * cond) libcfa_public __THROW {504 int pthread_cond_destroy(pthread_cond_t * cond) libcfa_public __THROW { 506 505 check_nonnull(cond); 507 506 destroy(cond); … … 513 512 //######################### Local storage ######################### 514 513 515 int pthread_once(pthread_once_t * once_control, void (*init_routine)(void)) libcfa_public __THROW {514 int pthread_once(pthread_once_t * once_control, void (* init_routine)(void)) libcfa_public __THROW { 516 515 static_assert(sizeof(pthread_once_t) >= sizeof(int),"sizeof(pthread_once_t) < sizeof(int)"); 517 516 check_nonnull(once_control); … … 526 525 } // pthread_once 527 526 528 int pthread_key_create( pthread_key_t * key, void (*destructor)( void * ) ) libcfa_public __THROW {527 int pthread_key_create( pthread_key_t * key, void (* destructor)( void * ) ) libcfa_public __THROW { 529 528 lock(key_lock); 530 529 for ( int i = 0; i < PTHREAD_KEYS_MAX; i += 1 ) { … … 561 560 } // pthread_key_delete 562 561 563 int pthread_setspecific( pthread_key_t key, const void * value ) libcfa_public __THROW {562 int pthread_setspecific( pthread_key_t key, const void * value ) libcfa_public __THROW { 564 563 // get current thread 565 cfaPthread * t = lookup(pthread_self());564 cfaPthread * t = lookup(pthread_self()); 566 565 // if current thread's pthreadData is NULL; initialize it 567 pthread_values * values;566 pthread_values * values; 568 567 if (t->pthreadData == NULL) { 569 568 values = anew( PTHREAD_KEYS_MAX); 570 569 t->pthreadData = values; 571 for ( int i = 0;i < PTHREAD_KEYS_MAX; i++ ) {570 for ( int i = 0;i < PTHREAD_KEYS_MAX; i++ ) { 572 571 t->pthreadData[i].in_use = false; 573 572 } // for … … 592 591 } //pthread_setspecific 593 592 594 void * pthread_getspecific(pthread_key_t key) libcfa_public __THROW {593 void * pthread_getspecific(pthread_key_t key) libcfa_public __THROW { 595 594 if (key >= PTHREAD_KEYS_MAX || ! cfa_pthread_keys[key].in_use) return NULL; 596 595 597 596 // get current thread 598 cfaPthread * t = lookup(pthread_self());597 cfaPthread * t = lookup(pthread_self()); 599 598 if (t->pthreadData == NULL) return NULL; 600 599 lock(key_lock); … … 604 603 return NULL; 605 604 } // if 606 void * value = entry.value;605 void * value = entry.value; 607 606 unlock(key_lock); 608 607 … … 905 904 } // pthread_cancel 906 905 907 int pthread_setcancelstate( int state, int * oldstate ) libcfa_public __THROW {906 int pthread_setcancelstate( int state, int * oldstate ) libcfa_public __THROW { 908 907 abort("pthread_setcancelstate not implemented"); 909 908 return 0; 910 909 } // pthread_setcancelstate 911 910 912 int pthread_setcanceltype( int type, int * oldtype ) libcfa_public __THROW {911 int pthread_setcanceltype( int type, int * oldtype ) libcfa_public __THROW { 913 912 abort("pthread_setcanceltype not implemented"); 914 913 return 0; … … 917 916 918 917 #pragma GCC diagnostic pop 919
Note: See TracChangeset
for help on using the changeset viewer.