Changeset f5f2768 for libcfa/src/concurrency/pthread.cfa
- Timestamp:
- Feb 16, 2023, 4:37:25 PM (18 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- fbdfcd8
- Parents:
- 1c80f20
- git-author:
- Peter A. Buhr <pabuhr@…> (02/16/23 16:34:37)
- git-committer:
- Peter A. Buhr <pabuhr@…> (02/16/23 16:37:25)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/pthread.cfa
r1c80f20 rf5f2768 15 15 16 16 #define __cforall_thread__ 17 #define _GNU_SOURCE18 17 19 18 #include <signal.h> … … 35 34 struct pthread_values{ 36 35 inline Seqable; 37 void * value;36 void * value; 38 37 bool in_use; 39 38 }; … … 55 54 }; 56 55 57 static void ?{}(pthread_keys& k) {56 static void ?{}(pthread_keys& k) { 58 57 k.threads{}; 59 58 } … … 62 61 static pthread_keys cfa_pthread_keys_storage[PTHREAD_KEYS_MAX] __attribute__((aligned (16))); 63 62 64 static void init_pthread_storage() {65 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++){63 static void init_pthread_storage() { 64 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++) { 66 65 cfa_pthread_keys_storage[i]{}; 67 66 } … … 96 95 97 96 /* condvar helper routines */ 98 static void init(pthread_cond_t * pcond){97 static void init(pthread_cond_t * pcond) { 99 98 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 100 cfa2pthr_cond_var_t * _cond = (cfa2pthr_cond_var_t*)pcond;99 cfa2pthr_cond_var_t * _cond = (cfa2pthr_cond_var_t*)pcond; 101 100 ?{}(*_cond); 102 101 } 103 102 104 static cfa2pthr_cond_var_t * get(pthread_cond_t* pcond){103 static cfa2pthr_cond_var_t * get(pthread_cond_t * pcond) { 105 104 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 106 105 return (cfa2pthr_cond_var_t*)pcond; 107 106 } 108 107 109 static void destroy(pthread_cond_t* cond) {108 static void destroy(pthread_cond_t* cond) { 110 109 static_assert(sizeof(pthread_cond_t) >= sizeof(cfa2pthr_cond_var_t),"sizeof(pthread_t) < sizeof(cfa2pthr_cond_var_t)"); 111 110 ^?{}(*get(cond)); … … 116 115 117 116 /* mutex helper routines */ 118 static void mutex_check(pthread_mutex_t* t) {117 static void mutex_check(pthread_mutex_t* t) { 119 118 // Use double check to improve performance. 120 119 // Check is safe on x86; volatile prevents compiler reordering … … 136 135 137 136 138 static void init(pthread_mutex_t* plock) {137 static void init(pthread_mutex_t* plock) { 139 138 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 140 139 simple_owner_lock* _lock = (simple_owner_lock*)plock; … … 142 141 } 143 142 144 static simple_owner_lock* get(pthread_mutex_t* plock) {143 static simple_owner_lock* get(pthread_mutex_t* plock) { 145 144 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 146 145 return (simple_owner_lock*)plock; 147 146 } 148 147 149 static void destroy(pthread_mutex_t* plock) {148 static void destroy(pthread_mutex_t* plock) { 150 149 static_assert(sizeof(pthread_mutex_t) >= sizeof(simple_owner_lock),"sizeof(pthread_mutex_t) < sizeof(simple_owner_lock)"); 151 150 ^?{}(*get(plock)); … … 173 172 }; 174 173 175 static cfaPthread_attr_t* get(const pthread_attr_t* attr) {174 static cfaPthread_attr_t* get(const pthread_attr_t* attr) { 176 175 static_assert(sizeof(pthread_attr_t) >= sizeof(cfaPthread_attr_t),"sizeof(pthread_attr_t) < sizeof(cfaPthread_attr_t)"); 177 176 return (cfaPthread_attr_t*)attr; … … 207 206 /* thread part routines */ 208 207 // cfaPthread entry point 209 void main( cfaPthread& _thread) with(_thread){210 joinval = start_routine(start_arg);208 void main( cfaPthread & _thread ) with( _thread ) { 209 joinval = start_routine( start_arg ); 211 210 isTerminated = true; 212 211 } 213 212 214 static cfaPthread * lookup( pthread_t p ){213 static cfaPthread * lookup( pthread_t p ) { 215 214 static_assert(sizeof(pthread_t) >= sizeof(cfaPthread*),"sizeof(pthread_t) < sizeof(cfaPthread*)"); 216 215 return (cfaPthread*)p; … … 221 220 pthread_keys* key; 222 221 bool destcalled = true; 223 if (values != NULL) {222 if (values != NULL) { 224 223 for ( int attempts = 0; attempts < PTHREAD_DESTRUCTOR_ITERATIONS && destcalled ; attempts += 1 ) { 225 224 destcalled = false; 226 225 lock(key_lock); 227 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++){226 for ( int i = 0; i < PTHREAD_KEYS_MAX; i++) { 228 227 // for each valid key 229 if ( values[i].in_use) {228 if ( values[i].in_use) { 230 229 value = &values[i]; 231 230 key = &cfa_pthread_keys[i]; … … 234 233 // if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with that key, 235 234 // the value of the key is set to NULL, and then the function pointed to is called with the previously associated value as its sole argument. 236 if (value->value != NULL && key->destructor != NULL) {235 if (value->value != NULL && key->destructor != NULL) { 237 236 unlock(key_lock); 238 237 key->destructor(value->value); // run destructor … … 249 248 } 250 249 251 static void ^?{}(cfaPthread & mutex t) {250 static void ^?{}(cfaPthread & mutex t) { 252 251 // delete pthread local storage 253 252 pthread_values * values = t.pthreadData; … … 260 259 // set up user thread stackSize 261 260 cfaPthread_attr_t * attr = get(_attr); 262 ((thread&)t) { attr ? attr->stacksize: DEFAULT_STACK_SIZE };261 ((thread&)t) { attr ? attr->stacksize: DEFAULT_STACK_SIZE }; 263 262 264 263 // initialize _thread & cfaPthread id … … 365 364 int pthread_create(pthread_t * _thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg) libcfa_public __THROW { 366 365 cfaPthread *t = alloc(); 367 (*t) {_thread, attr, start_routine, arg};366 (*t) {_thread, attr, start_routine, arg}; 368 367 return 0; 369 368 } … … 415 414 _thread->joinval = status; // set return value 416 415 _thread->isTerminated = 1; // set terminated flag 417 cancel_stack((pthread_exit_exp) {&exp_vt});416 cancel_stack((pthread_exit_exp) {&exp_vt}); 418 417 } //pthread_exit_ 419 418 … … 436 435 check_nonnull(_mutex); 437 436 simple_owner_lock* _lock = get(_mutex); 438 if (_lock->owner != NULL) {437 if (_lock->owner != NULL) { 439 438 return EBUSY; 440 439 } … … 454 453 check_nonnull(_mutex); 455 454 simple_owner_lock* _lock = get(_mutex); 456 if (_lock->owner != active_thread()) {455 if (_lock->owner != active_thread()) { 457 456 return EPERM; 458 457 } // current thread does not hold the mutex … … 464 463 check_nonnull(_mutex); 465 464 simple_owner_lock* _lock = get(_mutex); 466 if (_lock->owner != active_thread() && _lock->owner != NULL) {465 if (_lock->owner != active_thread() && _lock->owner != NULL) { 467 466 return EBUSY; 468 467 } // if mutex is owned … … 567 566 // if current thread's pthreadData is NULL; initialize it 568 567 pthread_values* values; 569 if (t->pthreadData == NULL) {568 if (t->pthreadData == NULL) { 570 569 values = anew( PTHREAD_KEYS_MAX); 571 570 t->pthreadData = values; 572 for ( int i = 0;i < PTHREAD_KEYS_MAX; i++){571 for ( int i = 0;i < PTHREAD_KEYS_MAX; i++) { 573 572 t->pthreadData[i].in_use = false; 574 573 } // for … … 875 874 //######################### Parallelism ######################### 876 875 877 int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {878 abort( "pthread_setaffinity_np" );879 } // pthread_setaffinity_np880 881 int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {882 abort( "pthread_getaffinity_np" );883 } // pthread_getaffinity_np884 885 int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {886 abort( "pthread_attr_setaffinity_np" );887 } // pthread_attr_setaffinity_np888 889 int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW {890 abort( "pthread_attr_getaffinity_np" );891 } // pthread_attr_getaffinity_np876 // int pthread_setaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 877 // abort( "pthread_setaffinity_np" ); 878 // } // pthread_setaffinity_np 879 880 // int pthread_getaffinity_np( pthread_t /* __th */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 881 // abort( "pthread_getaffinity_np" ); 882 // } // pthread_getaffinity_np 883 884 // int pthread_attr_setaffinity_np( pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, __const cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 885 // abort( "pthread_attr_setaffinity_np" ); 886 // } // pthread_attr_setaffinity_np 887 888 // int pthread_attr_getaffinity_np( __const pthread_attr_t * /* __attr */, size_t /* __cpusetsize */, cpu_set_t * /* __cpuset */ ) libcfa_public __THROW { 889 // abort( "pthread_attr_getaffinity_np" ); 890 // } // pthread_attr_getaffinity_np 892 891 893 892 //######################### Cancellation #########################
Note: See TracChangeset
for help on using the changeset viewer.