Changeset 93d2219 for libcfa/src
- Timestamp:
- Oct 28, 2022, 3:12:16 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- fa2e183
- Parents:
- e874605 (diff), 22a0e87 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- libcfa/src
- Files:
-
- 3 added
- 2 deleted
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/Makefile.am
re874605 r93d2219 62 62 containers/array.hfa \ 63 63 containers/list.hfa \ 64 containers/queueLockFree.hfa \ 65 containers/stackLockFree.hfa \ 64 containers/lockfree.hfa \ 66 65 containers/string_sharectx.hfa \ 67 66 containers/vector2.hfa \ … … 127 126 128 127 thread_libsrc = ${inst_thread_headers_src} ${inst_thread_headers_src:.hfa=.cfa} \ 128 interpose_thread.cfa \ 129 129 bits/signal.hfa \ 130 130 concurrency/clib/cfathread.cfa \ … … 145 145 concurrency/stats.cfa \ 146 146 concurrency/stats.hfa \ 147 concurrency/stats.hfa 147 concurrency/stats.hfa \ 148 concurrency/pthread.cfa 148 149 149 150 else -
libcfa/src/concurrency/clib/cfathread.cfa
re874605 r93d2219 172 172 173 173 pthread_attr_t attr; 174 if (int ret = pthread_attr_init(&attr); 0 != ret) {174 if (int ret = __cfaabi_pthread_attr_init(&attr); 0 != ret) { 175 175 abort | "failed to create master epoll thread attr: " | ret | strerror(ret); 176 176 } 177 177 178 if (int ret = pthread_create(&master_poller, &attr, master_epoll, 0p); 0 != ret) {178 if (int ret = __cfaabi_pthread_create(&master_poller, &attr, master_epoll, 0p); 0 != ret) { 179 179 abort | "failed to create master epoll thread: " | ret | strerror(ret); 180 180 } -
libcfa/src/concurrency/invoke.h
re874605 r93d2219 214 214 215 215 #if defined( __CFA_WITH_VERIFY__ ) 216 struct processor * volatile executing; 216 217 void * canary; 217 218 #endif -
libcfa/src/concurrency/io.cfa
re874605 r93d2219 610 610 if( we ) { 611 611 sigval_t value = { PREEMPT_IO }; 612 pthread_sigqueue(ctx->proc->kernel_thread, SIGUSR1, value);612 __cfaabi_pthread_sigqueue(ctx->proc->kernel_thread, SIGUSR1, value); 613 613 } 614 614 -
libcfa/src/concurrency/io/setup.cfa
re874605 r93d2219 344 344 // iopoll.run = false; 345 345 // sigval val = { 1 }; 346 // pthread_sigqueue( iopoll.thrd, SIGUSR1, val );346 // __cfaabi_pthread_sigqueue( iopoll.thrd, SIGUSR1, val ); 347 347 348 348 // // Make sure all this is done -
libcfa/src/concurrency/kernel.cfa
re874605 r93d2219 321 321 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor 322 322 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor 323 /* paranoid */ verify( __atomic_exchange_n( &thrd_dst->executing, this, __ATOMIC_SEQ_CST) == 0p ); 323 324 /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd_dst->canary ); 324 325 … … 332 333 333 334 /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd_dst->canary ); 335 /* paranoid */ verify( __atomic_exchange_n( &thrd_dst->executing, 0p, __ATOMIC_SEQ_CST) == this ); 334 336 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); 335 337 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); 338 /* paranoid */ verify( thrd_dst->state != Halted ); 336 339 /* paranoid */ verify( thrd_dst->context.SP ); 337 /* paranoid */ verify( thrd_dst->curr_cluster == this->cltr );338 340 /* paranoid */ verify( kernelTLS().this_thread == thrd_dst ); 339 341 /* paranoid */ verify( ! __preemption_enabled() ); -
libcfa/src/concurrency/kernel.hfa
re874605 r93d2219 160 160 // P9_EMBEDDED( processor, dlink(processor) ) 161 161 static inline tytagref( dlink(processor), dlink(processor) ) ?`inner( processor & this ) { 162 163 164 162 dlink(processor) & b = this.link; 163 tytagref( dlink(processor), dlink(processor) ) result = { b }; 164 return result; 165 165 } 166 166 … … 269 269 io_context_params params; 270 270 } io; 271 272 struct { 273 struct processor ** procs; 274 unsigned cnt; 275 } managed; 271 276 272 277 #if !defined(__CFA_NO_STATISTICS__) … … 298 303 static inline struct cluster * active_cluster () { return publicTLS_get( this_processor )->cltr; } 299 304 305 // set the number of internal processors 306 // these processors are in addition to any explicitly declared processors 307 unsigned set_concurrency( cluster & this, unsigned new_count ); 308 300 309 #if !defined(__CFA_NO_STATISTICS__) 301 310 void print_stats_now( cluster & this, int flags ); -
libcfa/src/concurrency/kernel/private.hfa
re874605 r93d2219 20 20 #endif 21 21 22 #include <signal.h> 23 22 24 #include "kernel.hfa" 23 25 #include "thread.hfa" … … 48 50 #endif 49 51 #endif 50 51 52 // #define READYQ_USE_LINEAR_AVG 52 53 #define READYQ_USE_LOGDBL_AVG … … 62 63 #error must pick a scheme for averaging 63 64 #endif 65 66 extern "C" { 67 __attribute__((visibility("protected"))) int __cfaabi_pthread_create(pthread_t *_thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 68 __attribute__((visibility("protected"))) int __cfaabi_pthread_join(pthread_t _thread, void **retval); 69 __attribute__((visibility("protected"))) pthread_t __cfaabi_pthread_self(void); 70 __attribute__((visibility("protected"))) int __cfaabi_pthread_attr_init(pthread_attr_t *attr); 71 __attribute__((visibility("protected"))) int __cfaabi_pthread_attr_destroy(pthread_attr_t *attr); 72 __attribute__((visibility("protected"))) int __cfaabi_pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize ); 73 __attribute__((visibility("protected"))) int __cfaabi_pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ); 74 __attribute__((visibility("protected"))) int __cfaabi_pthread_sigqueue(pthread_t _thread, int sig, const union sigval value); 75 __attribute__((visibility("protected"))) int __cfaabi_pthread_sigmask( int how, const sigset_t *set, sigset_t *oset); 76 } 64 77 65 78 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/kernel/startup.cfa
re874605 r93d2219 16 16 #define __cforall_thread__ 17 17 #define _GNU_SOURCE 18 19 // #define __CFA_DEBUG_PRINT_RUNTIME_CORE__ 18 20 19 21 // C Includes … … 222 224 ( this.runner ){}; 223 225 init( this, "Main Processor", *mainCluster, 0p ); 224 kernel_thread = pthread_self();226 kernel_thread = __cfaabi_pthread_self(); 225 227 226 228 runner{ &this }; … … 283 285 } 284 286 287 extern "C"{ 288 void pthread_delete_kernel_threads_(); 289 } 290 291 285 292 static void __kernel_shutdown(void) { 286 293 if(!cfa_main_returned) return; 294 295 //delete kernel threads for pthread_concurrency 296 pthread_delete_kernel_threads_(); 297 287 298 /* paranoid */ verify( __preemption_enabled() ); 288 299 disable_interrupts(); … … 327 338 328 339 /* paranoid */ verify( this.do_terminate == true ); 329 __cfa abi_dbg_print_safe("Kernel : destroyed main processor context %p\n", &runner);340 __cfadbg_print_safe(runtime_core, "Kernel : destroyed main processor context %p\n", &runner); 330 341 } 331 342 … … 388 399 (proc->runner){ proc, &info }; 389 400 390 __cfa abi_dbg_print_safe("Coroutine : created stack %p\n", get_coroutine(proc->runner)->stack.storage);401 __cfadbg_print_safe(runtime_core, "Coroutine : created stack %p\n", get_coroutine(proc->runner)->stack.storage); 391 402 392 403 //Set global state … … 520 531 random_state = __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl(); 521 532 #if defined( __CFA_WITH_VERIFY__ ) 533 executing = 0p; 522 534 canary = 0x0D15EA5E0D15EA5Ep; 523 535 #endif … … 652 664 io.params = io_params; 653 665 666 managed.procs = 0p; 667 managed.cnt = 0; 668 654 669 doregister(this); 655 670 … … 667 682 668 683 void ^?{}(cluster & this) libcfa_public { 684 set_concurrency( this, 0 ); 685 669 686 destroy(this.io.arbiter); 670 687 … … 777 794 pthread_attr_t attr; 778 795 779 check( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute796 check( __cfaabi_pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute 780 797 781 798 size_t stacksize = max( PTHREAD_STACK_MIN, DEFAULT_STACK_SIZE ); … … 804 821 #endif 805 822 806 check( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );807 check( pthread_create( pthread, &attr, start, arg ), "pthread_create" );823 check( __cfaabi_pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" ); 824 check( __cfaabi_pthread_create( pthread, &attr, start, arg ), "pthread_create" ); 808 825 return stack; 809 826 } 810 827 811 828 void __destroy_pthread( pthread_t pthread, void * stack, void ** retval ) { 812 int err = pthread_join( pthread, retval );829 int err = __cfaabi_pthread_join( pthread, retval ); 813 830 if( err != 0 ) abort("KERNEL ERROR: joining pthread %p caused error %s\n", (void*)pthread, strerror(err)); 814 831 … … 816 833 pthread_attr_t attr; 817 834 818 check( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute835 check( __cfaabi_pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute 819 836 820 837 size_t stacksize; 821 838 // default stack size, normally defined by shell limit 822 check( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" );839 check( __cfaabi_pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" ); 823 840 assert( stacksize >= PTHREAD_STACK_MIN ); 824 841 stacksize += __page_size; … … 838 855 } 839 856 857 unsigned set_concurrency( cluster & this, unsigned new ) libcfa_public { 858 unsigned old = this.managed.cnt; 859 860 __cfadbg_print_safe(runtime_core, "Kernel : resizing cluster from %u to %u\n", old, (unsigned)new); 861 862 // Delete all the old unneeded procs 863 if(old > new) for(i; (unsigned)new ~ old) { 864 __cfadbg_print_safe(runtime_core, "Kernel : destroying %u\n", i); 865 delete( this.managed.procs[i] ); 866 } 867 868 // Allocate new array (uses realloc and memcpies the data) 869 this.managed.procs = alloc( new, this.managed.procs`realloc ); 870 this.managed.cnt = new; 871 872 // Create the desired new procs 873 if(old < new) for(i; old ~ new) { 874 __cfadbg_print_safe(runtime_core, "Kernel : constructing %u\n", i); 875 (*(this.managed.procs[i] = alloc())){ this }; 876 } 877 878 // return the old count 879 return old; 880 } 881 840 882 #if defined(__CFA_WITH_VERIFY__) 841 883 static bool verify_fwd_bck_rng(void) { -
libcfa/src/concurrency/locks.hfa
re874605 r93d2219 21 21 22 22 #include "bits/weakso_locks.hfa" 23 #include "containers/ queueLockFree.hfa"23 #include "containers/lockfree.hfa" 24 24 #include "containers/list.hfa" 25 25 … … 423 423 } 424 424 425 static inline size_t on_wait(simple_owner_lock & this) with(this) { 425 static inline size_t on_wait(simple_owner_lock & this) with(this) { 426 426 lock( lock __cfaabi_dbg_ctx2 ); 427 427 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); -
libcfa/src/concurrency/preemption.cfa
re874605 r93d2219 352 352 sigset_t oldset; 353 353 int ret; 354 ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset); // workaround trac#208: cast should be unnecessary354 ret = __cfaabi_pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset); // workaround trac#208: cast should be unnecessary 355 355 if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); } 356 356 … … 385 385 sigaddset( &mask, sig ); 386 386 387 if ( pthread_sigmask( SIG_UNBLOCK, &mask, 0p ) == -1 ) {387 if ( __cfaabi_pthread_sigmask( SIG_UNBLOCK, &mask, 0p ) == -1 ) { 388 388 abort( "internal error, pthread_sigmask" ); 389 389 } … … 396 396 sigaddset( &mask, sig ); 397 397 398 if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {398 if ( __cfaabi_pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) { 399 399 abort( "internal error, pthread_sigmask" ); 400 400 } … … 404 404 static void preempt( processor * this ) { 405 405 sigval_t value = { PREEMPT_NORMAL }; 406 pthread_sigqueue( this->kernel_thread, SIGUSR1, value );406 __cfaabi_pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); 407 407 } 408 408 … … 415 415 sigset_t oldset; 416 416 int ret; 417 ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset); // workaround trac#208: cast should be unnecessary417 ret = __cfaabi_pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset); // workaround trac#208: cast should be unnecessary 418 418 if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); } 419 419 … … 434 434 sigset_t oldset; 435 435 int ret; 436 ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset); // workaround trac#208: cast should be unnecessary436 ret = __cfaabi_pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset); // workaround trac#208: cast should be unnecessary 437 437 if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); } 438 438 … … 505 505 sigval val; 506 506 val.sival_int = 0; 507 pthread_sigqueue( alarm_thread, SIGALRM, val );507 __cfaabi_pthread_sigqueue( alarm_thread, SIGALRM, val ); 508 508 509 509 // Wait for the preemption thread to finish … … 579 579 static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" ); 580 580 #endif 581 if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), 0p ) == -1 ) {581 if ( __cfaabi_pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), 0p ) == -1 ) { 582 582 abort( "internal error, sigprocmask" ); 583 583 } … … 607 607 sigset_t mask; 608 608 sigfillset(&mask); 609 if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {609 if ( __cfaabi_pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) { 610 610 abort( "internal error, pthread_sigmask" ); 611 611 } -
libcfa/src/concurrency/thread.cfa
re874605 r93d2219 50 50 random_state = __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl(); 51 51 #if defined( __CFA_WITH_VERIFY__ ) 52 executing = 0p; 52 53 canary = 0x0D15EA5E0D15EA5Ep; 53 54 #endif … … 177 178 178 179 //----------------------------------------------------------------------------- 180 bool migrate( thread$ * thrd, struct cluster & cl ) { 181 182 monitor$ * tmon = get_monitor(thrd); 183 monitor$ * __monitors[] = { tmon }; 184 monitor_guard_t __guard = { __monitors, 1 }; 185 186 187 { 188 // if nothing needs to be done, return false 189 if( thrd->curr_cluster == &cl ) return false; 190 191 // are we migrating ourself? 192 const bool local = thrd == active_thread(); 193 194 /* paranoid */ verify( !local || &cl != active_cluster() ); 195 /* paranoid */ verify( !local || thrd->curr_cluster == active_cluster() ); 196 /* paranoid */ verify( !local || thrd->curr_cluster == active_processor()->cltr ); 197 /* paranoid */ verify( local || tmon->signal_stack.top->owner->waiting_thread == thrd ); 198 /* paranoid */ verify( local || tmon->signal_stack.top ); 199 200 // make sure we aren't interrupted while doing this 201 // not as important if we aren't local 202 disable_interrupts(); 203 204 // actually move the thread 205 unregister( thrd->curr_cluster, *thrd ); 206 thrd->curr_cluster = &cl; 207 doregister( thrd->curr_cluster, *thrd ); 208 209 // restore interrupts 210 enable_interrupts(); 211 212 // if this is the local thread, we are still running on the old cluster 213 if(local) yield(); 214 215 /* paranoid */ verify( !local || &cl == active_cluster() ); 216 /* paranoid */ verify( !local || thrd->curr_cluster == active_cluster() ); 217 /* paranoid */ verify( !local || thrd->curr_cluster == active_processor()->cltr ); 218 /* paranoid */ verify( local || tmon->signal_stack.top ); 219 /* paranoid */ verify( local || tmon->signal_stack.top->owner->waiting_thread == thrd ); 220 221 return true; 222 } 223 } 224 225 //----------------------------------------------------------------------------- 179 226 #define GENERATOR LCG 180 227 -
libcfa/src/concurrency/thread.hfa
re874605 r93d2219 132 132 133 133 //---------- 134 // misc 135 bool migrate( thread$ * thrd, struct cluster & cl ); 136 137 forall( T & | is_thread(T) ) 138 static inline bool migrate( T & mutex thrd, struct cluster & cl ) { return migrate( &(thread&)thrd, cl ); } 139 140 141 //---------- 134 142 // prng 135 143 static inline { -
libcfa/src/containers/array.hfa
re874605 r93d2219 1 #pragma once 2 1 3 #include <assert.h> 2 4 … … 18 20 // About the choice of integral types offered as subscript overloads: 19 21 // Intent is to cover these use cases: 22 // a[0] // i : zero_t 23 // a[1] // i : one_t 24 // a[2] // i : int 20 25 // float foo( ptrdiff_t i ) { return a[i]; } // i : ptrdiff_t 26 // float foo( size_t i ) { return a[i]; } // i : size_t 21 27 // forall( [N] ) ... for( i; N ) { total += a[i]; } // i : typeof( sizeof(42) ) 22 28 // for( i; 5 ) { total += a[i]; } // i : int 29 // 23 30 // It gets complicated by: 24 31 // - CFA does overloading on concrete types, like int and unsigned int, not on typedefed … … 27 34 // - Given bug of Trac #247, CFA gives sizeof expressions type unsigned long int, when it 28 35 // should give them type size_t. 29 // 30 // gcc -m32 cfa -m32 given bug gcc -m64 36 // 37 // gcc -m32 cfa -m32 given bug gcc -m64 (and cfa) 31 38 // ptrdiff_t int int long int 32 39 // size_t unsigned int unsigned int unsigned long int 33 40 // typeof( sizeof(42) ) unsigned int unsigned long int unsigned long int 34 41 // int int int int 42 // 43 // So the solution must support types {zero_t, one_t, int, unsigned int, long int, unsigned long int} 44 // 45 // The solution cannot rely on implicit conversions (e.g. just have one overload for ptrdiff_t) 46 // because assertion satisfaction requires types to match exacly. Both higher-dimensional 47 // subscripting and operations on slices use asserted subscript operators. The test case 48 // array-container/array-sbscr-cases covers the combinations. Mike beleives that commenting out 49 // any of the current overloads leads to one of those cases failing, either on 64- or 32-bit. 50 // Mike is open to being shown a smaller set of overloads that still passes the test. 51 52 static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, zero_t ) { 53 assert( 0 < N ); 54 return (Timmed &) a.strides[0]; 55 } 56 57 static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, one_t ) { 58 assert( 1 < N ); 59 return (Timmed &) a.strides[1]; 60 } 35 61 36 62 static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, int i ) { … … 39 65 } 40 66 67 static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, int i ) { 68 assert( i < N ); 69 return (Timmed &) a.strides[i]; 70 } 71 41 72 static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned int i ) { 42 73 assert( i < N ); … … 44 75 } 45 76 77 static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, unsigned int i ) { 78 assert( i < N ); 79 return (Timmed &) a.strides[i]; 80 } 81 46 82 static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, long int i ) { 47 83 assert( i < N ); … … 49 85 } 50 86 87 static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, long int i ) { 88 assert( i < N ); 89 return (Timmed &) a.strides[i]; 90 } 91 51 92 static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) { 93 assert( i < N ); 94 return (Timmed &) a.strides[i]; 95 } 96 97 static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) { 52 98 assert( i < N ); 53 99 return (Timmed &) a.strides[i]; … … 57 103 return N; 58 104 } 105 106 static inline void __taglen( tag(arpk(N, S, Timmed, Tbase)), tag(N) ) {} 59 107 60 108 // workaround #226 (and array relevance thereof demonstrated in mike102/otype-slow-ndims.cfa) … … 83 131 // Make a FOREACH macro 84 132 #define FE_0(WHAT) 85 #define FE_1(WHAT, X) WHAT(X) 133 #define FE_1(WHAT, X) WHAT(X) 86 134 #define FE_2(WHAT, X, ...) WHAT(X)FE_1(WHAT, __VA_ARGS__) 87 135 #define FE_3(WHAT, X, ...) WHAT(X)FE_2(WHAT, __VA_ARGS__) … … 90 138 //... repeat as needed 91 139 92 #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME 140 #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME 93 141 #define FOR_EACH(action,...) \ 94 142 GET_MACRO(_0,__VA_ARGS__,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)(action,__VA_ARGS__) … … 115 163 } 116 164 117 #else 165 #else 118 166 119 167 // Workaround form. Listing all possibilities up to 4 dims. … … 135 183 136 184 #endif 185 186 // Available for users to work around Trac #265 187 // If `a[...0...]` isn't working, try `a[...ix0...]` instead. 188 189 #define ix0 ((ptrdiff_t)0) 190 191 137 192 138 193 // … … 155 210 156 211 // Wrapper 157 struct all_t {} all;212 extern struct all_t {} all; 158 213 forall( [N], S & | sized(S), Te &, result &, Tbase & | { tag(result) enq_( tag(Tbase), tag(N), tag(S), tag(Te) ); } ) 159 214 static inline result & ?[?]( arpk(N, S, Te, Tbase) & this, all_t ) { … … 165 220 // 166 221 167 trait ar(A &, Tv &) { 168 Tv& ?[?]( A&, ptrdiff_t ); 169 size_t ?`len( A& ); 170 }; 222 // desired: 223 // trait ar(A &, Tv &, [N]) { 224 // Tv& ?[?]( A&, zero_t ); 225 // Tv& ?[?]( A&, one_t ); 226 // Tv& ?[?]( A&, int ); 227 // ... 228 // size_t ?`len( A& ); 229 // void __taglen( tag(C), tag(N) ); 230 // }; 231 232 // working around N's not being accepted as arguments to traits 233 234 #define ar(A, Tv, N) { \ 235 Tv& ?[?]( A&, zero_t ); \ 236 Tv& ?[?]( A&, one_t ); \ 237 Tv& ?[?]( A&, int ); \ 238 Tv& ?[?]( A&, unsigned int ); \ 239 Tv& ?[?]( A&, long int ); \ 240 Tv& ?[?]( A&, unsigned long int ); \ 241 size_t ?`len( A& ); \ 242 void __taglen( tag(A), tag(N) ); \ 243 } -
libcfa/src/device/cpu.cfa
re874605 r93d2219 359 359 int idxs = count_cache_indexes(); 360 360 361 // Do we actually have a cache? 362 if(idxs == 0) { 363 // if not just fake the data structure, it makes things easier. 364 cpu_info.hthrd_count = cpus_c; 365 cpu_info.llc_count = 0; 366 struct cpu_map_entry_t * entries = alloc(cpu_info.hthrd_count); 367 for(i; cpu_info.hthrd_count) { 368 entries[i].self = i; 369 entries[i].start = 0; 370 entries[i].count = cpu_info.hthrd_count; 371 entries[i].cache = 0; 372 } 373 cpu_info.llc_map = entries; 374 return; 375 } 376 361 377 // Count actual cache levels 362 378 unsigned cache_levels = 0; 363 379 unsigned llc = 0; 364 if (idxs != 0) { 365 unsigned char prev = -1u; 366 void first(unsigned idx, unsigned char level, const char * map, size_t len) { 367 /* paranoid */ verifyf(level < prev, "Index %u of cpu 0 has cache levels out of order: %u then %u", idx, (unsigned)prev, (unsigned)level); 368 llc = max(llc, level); 369 prev = level; 370 cache_levels++; 371 } 372 foreach_cacheidx(0, idxs, first); 373 } 380 381 unsigned char prev = -1u; 382 void first(unsigned idx, unsigned char level, const char * map, size_t len) { 383 /* paranoid */ verifyf(level < prev, "Index %u of cpu 0 has cache levels out of order: %u then %u", idx, (unsigned)prev, (unsigned)level); 384 llc = max(llc, level); 385 prev = level; 386 cache_levels++; 387 } 388 foreach_cacheidx(0, idxs, first); 374 389 375 390 // Read in raw data -
libcfa/src/heap.cfa
re874605 r93d2219 211 211 #if BUCKETLOCK == SPINLOCK 212 212 #elif BUCKETLOCK == LOCKFREE 213 #include < stackLockFree.hfa>213 #include <containers/lockfree.hfa> 214 214 #else 215 215 #error undefined lock type for bucket lock … … 505 505 freeLists[j].blockSize = bucketSizes[j]; 506 506 } // for 507 507 508 508 heapBuffer = 0p; 509 509 heapReserve = 0; -
libcfa/src/interpose.cfa
re874605 r93d2219 42 42 43 43 typedef void (* generic_fptr_t)(void); 44 static generic_fptr_t do_interpose_symbol( void * library, const char symbol[], const char version[] ) { 45 const char * error; 46 47 union { generic_fptr_t fptr; void * ptr; } originalFunc; 48 49 #if defined( _GNU_SOURCE ) 50 if ( version ) { 51 originalFunc.ptr = dlvsym( library, symbol, version ); 52 } else { 53 originalFunc.ptr = dlsym( library, symbol ); 54 } 55 #else 56 originalFunc.ptr = dlsym( library, symbol ); 57 #endif // _GNU_SOURCE 58 59 error = dlerror(); 60 if ( error ) abort( "interpose_symbol : internal error, %s\n", error ); 61 62 return originalFunc.fptr; 63 } 64 44 65 static generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) { 45 66 const char * error; 46 67 47 68 static void * library; 69 static void * pthread_library; 48 70 if ( ! library ) { 49 71 #if defined( RTLD_NEXT ) … … 58 80 #endif 59 81 } // if 60 61 union { generic_fptr_t fptr; void * ptr; } originalFunc; 62 63 #if defined( _GNU_SOURCE ) 64 if ( version ) { 65 originalFunc.ptr = dlvsym( library, symbol, version ); 66 } else { 67 originalFunc.ptr = dlsym( library, symbol ); 68 } 69 #else 70 originalFunc.ptr = dlsym( library, symbol ); 71 #endif // _GNU_SOURCE 72 73 error = dlerror(); 74 if ( error ) abort( "interpose_symbol : internal error, %s\n", error ); 75 76 return originalFunc.fptr; 82 if ( ! pthread_library ) { 83 #if defined( RTLD_NEXT ) 84 pthread_library = RTLD_NEXT; 85 #else 86 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 87 pthread_library = dlopen( "libpthread.so", RTLD_LAZY ); 88 error = dlerror(); 89 if ( error ) { 90 abort( "interpose_symbol : failed to open libpthread, %s\n", error ); 91 } 92 #endif 93 } // if 94 95 return do_interpose_symbol(library, symbol, version); 77 96 } 78 97 … … 97 116 98 117 extern "C" { 118 void __cfathreadabi_interpose_startup( generic_fptr_t (*do_interpose_symbol)( void * library, const char symbol[], const char version[] ) ) __attribute__((weak)); 99 119 void __cfaabi_interpose_startup( void ) { 100 120 const char *version = 0p; … … 108 128 INTERPOSE_LIBC( exit , version ); 109 129 #pragma GCC diagnostic pop 130 131 if(__cfathreadabi_interpose_startup) __cfathreadabi_interpose_startup( do_interpose_symbol ); 110 132 111 133 // As a precaution (and necessity), errors that result in termination are delivered on a separate stack because -
libcfa/src/parseargs.cfa
re874605 r93d2219 50 50 extern char ** cfa_args_envp __attribute__((weak)); 51 51 52 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out) __attribute__ ((noreturn)); 52 forall([N]) 53 static void usage(char * cmd, const array( cfa_option, N ) & options, const char * usage, FILE * out) __attribute__ ((noreturn)); 53 54 //----------------------------------------------------------------------------- 54 55 // checking 55 static void check_args(cfa_option options[], size_t opt_count) { 56 for(i; opt_count) { 57 for(j; opt_count) { 56 forall([N]) 57 static void check_args( const array( cfa_option, N ) & options ) { 58 for(i; N) { 59 for(j; N) { 58 60 if(i == j) continue; 59 61 … … 70 72 //----------------------------------------------------------------------------- 71 73 // Parsing args 72 void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) { 73 if( 0p != &cfa_args_argc ) { 74 parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left ); 75 } 76 else { 77 char * temp = ""; 78 parse_args(0, &temp, options, opt_count, usage, left ); 79 } 80 } 81 82 void parse_args( 83 int argc, 84 char * argv[], 85 cfa_option options[], 86 size_t opt_count, 87 const char * usage, 88 char ** & left 89 ) { 90 check_args(options, opt_count); 91 92 int maxv = 'h'; 93 char optstring[(opt_count * 3) + 2] = { '\0' }; 94 { 95 int idx = 0; 96 for(i; opt_count) { 97 if (options[i].short_name) { 98 maxv = max(options[i].short_name, maxv); 99 optstring[idx] = options[i].short_name; 100 idx++; 101 if( ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue) 102 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) { 103 optstring[idx] = ':'; 74 forall([opt_count]) { 75 void parse_args( const array( cfa_option, opt_count ) & options, const char * usage, char ** & left ) { 76 if( 0p != &cfa_args_argc ) { 77 parse_args(cfa_args_argc, cfa_args_argv, options, usage, left ); 78 } 79 else { 80 char * temp = ""; 81 parse_args(0, &temp, options, usage, left ); 82 } 83 } 84 85 void parse_args( 86 int argc, 87 char * argv[], 88 const array( cfa_option, opt_count ) & options, 89 const char * usage, 90 char ** & left 91 ) { 92 check_args(options); 93 94 int maxv = 'h'; 95 char optstring[(opt_count * 3) + 2] = { '\0' }; 96 { 97 int idx = 0; 98 for(i; opt_count) { 99 if (options[i].short_name) { 100 maxv = max(options[i].short_name, maxv); 101 optstring[idx] = options[i].short_name; 102 idx++; 103 if( ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue) 104 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) { 105 optstring[idx] = ':'; 106 idx++; 107 } 108 } 109 } 110 optstring[idx+0] = 'h'; 111 optstring[idx+1] = '\0'; 112 } 113 114 struct option optarr[opt_count + 2]; 115 { 116 int idx = 0; 117 for(i; opt_count) { 118 if(options[i].long_name) { 119 // we don't have the mutable keyword here, which is really what we would want 120 int & val_ref = (int &)(const int &)options[i].val; 121 val_ref = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv; 122 123 optarr[idx].name = options[i].long_name; 124 optarr[idx].flag = 0p; 125 optarr[idx].val = options[i].val; 126 if( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue) 127 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) { 128 optarr[idx].has_arg = no_argument; 129 } else { 130 optarr[idx].has_arg = required_argument; 131 } 104 132 idx++; 105 133 } 106 134 } 107 } 108 optstring[idx+0] = 'h'; 109 optstring[idx+1] = '\0'; 110 } 111 112 struct option optarr[opt_count + 2]; 113 { 114 int idx = 0; 115 for(i; opt_count) { 116 if(options[i].long_name) { 117 options[i].val = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv; 118 optarr[idx].name = options[i].long_name; 119 optarr[idx].flag = 0p; 120 optarr[idx].val = options[i].val; 121 if( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue) 122 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) { 123 optarr[idx].has_arg = no_argument; 124 } else { 125 optarr[idx].has_arg = required_argument; 126 } 127 idx++; 135 optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h']; 136 optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0]; 137 } 138 139 FILE * out = stderr; 140 NEXT_ARG: 141 for() { 142 int idx = 0; 143 int opt = getopt_long(argc, argv, optstring, optarr, &idx); 144 switch(opt) { 145 case -1: 146 if(&left != 0p) left = argv + optind; 147 return; 148 case 'h': 149 out = stdout; 150 case '?': 151 usage(argv[0], options, usage, out); 152 default: 153 for(i; opt_count) { 154 if(opt == options[i].val) { 155 const char * arg = optarg ? optarg : ""; 156 if( arg[0] == '=' ) { arg++; } 157 // work around for some weird bug 158 void * variable = options[i].variable; 159 bool (*parse_func)(const char *, void * ) = options[i].parse; 160 bool success = parse_func( arg, variable ); 161 if(success) continue NEXT_ARG; 162 163 fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt); 164 usage(argv[0], options, usage, out); 165 } 166 } 167 abort("Internal parse arg error\n"); 128 168 } 129 } 130 optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h']; 131 optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0]; 132 } 133 134 FILE * out = stderr; 135 NEXT_ARG: 136 for() { 137 int idx = 0; 138 int opt = getopt_long(argc, argv, optstring, optarr, &idx); 139 switch(opt) { 140 case -1: 141 if(&left != 0p) left = argv + optind; 142 return; 143 case 'h': 144 out = stdout; 145 case '?': 146 usage(argv[0], options, opt_count, usage, out); 147 default: 148 for(i; opt_count) { 149 if(opt == options[i].val) { 150 const char * arg = optarg ? optarg : ""; 151 if( arg[0] == '=' ) { arg++; } 152 bool success = options[i].parse( arg, options[i].variable ); 153 if(success) continue NEXT_ARG; 154 155 fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt); 156 usage(argv[0], options, opt_count, usage, out); 157 } 158 } 159 abort("Internal parse arg error\n"); 160 } 161 169 170 } 162 171 } 163 172 } … … 222 231 223 232 void print_args_usage(cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)) { 224 usage(cfa_args_argv[0], options, opt_count, usage, error ? stderr : stdout); 233 const array( cfa_option, opt_count ) & arr = (const array( cfa_option, opt_count ) &) *options; 234 usage(cfa_args_argv[0], arr, usage, error ? stderr : stdout); 225 235 } 226 236 227 237 void print_args_usage(int , char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)) { 228 usage(argv[0], options, opt_count, usage, error ? stderr : stdout); 229 } 230 231 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * help, FILE * out) __attribute__((noreturn)) { 238 const array( cfa_option, opt_count ) & arr = (const array( cfa_option, opt_count ) &) *options; 239 usage(argv[0], arr, usage, error ? stderr : stdout); 240 } 241 242 forall( [N] ) { 243 void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error) { 244 usage(cfa_args_argv[0], options, usage, error ? stderr : stdout); 245 } 246 247 void print_args_usage(int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error) { 248 usage(argv[0], options, usage, error ? stderr : stdout); 249 } 250 } 251 252 forall([N]) 253 static void usage(char * cmd, const array( cfa_option, N ) & options, const char * help, FILE * out) __attribute__((noreturn)) { 232 254 int width = 0; 233 255 { 234 for(i; opt_count) {256 for(i; N) { 235 257 if(options[i].long_name) { 236 258 int w = strlen(options[i].long_name); … … 251 273 fprintf(out, "Usage:\n %s %s\n", cmd, help); 252 274 253 for(i; opt_count) {275 for(i; N) { 254 276 printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help); 255 277 } -
libcfa/src/parseargs.hfa
re874605 r93d2219 16 16 #pragma once 17 17 18 #include <array.hfa> 19 18 20 struct cfa_option { 19 20 21 22 23 24 21 int val; // reserved 22 char short_name; 23 const char * long_name; 24 const char * help; 25 void * variable; 26 bool (*parse)(const char *, void * ); 25 27 }; 26 28 … … 31 33 forall(T & | { bool parse(const char *, T & ); }) 32 34 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) { 33 34 35 36 37 38 35 this.val = 0; 36 this.short_name = short_name; 37 this.long_name = long_name; 38 this.help = help; 39 this.variable = (void*)&variable; 40 this.parse = (bool (*)(const char *, void * ))parse; 39 41 } 40 42 41 43 forall(T &) 42 44 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) { 43 44 45 46 47 48 45 this.val = 0; 46 this.short_name = short_name; 47 this.long_name = long_name; 48 this.help = help; 49 this.variable = (void*)&variable; 50 this.parse = (bool (*)(const char *, void * ))parse; 49 51 } 50 52 … … 52 54 void parse_args( int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, char ** & left ); 53 55 56 forall( [N] ) { 57 void parse_args( const array( cfa_option, N ) & options, const char * usage, char ** & left ); 58 void parse_args( int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, char ** & left ); 59 } 60 54 61 void print_args_usage(cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)); 55 62 void print_args_usage(int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)); 63 64 forall( [N] ) { 65 void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error) __attribute__ ((noreturn)); 66 void print_args_usage(int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error) __attribute__ ((noreturn)); 67 } 56 68 57 69 bool parse_yesno (const char *, bool & );
Note:
See TracChangeset
for help on using the changeset viewer.