Changes in / [e874605:93d2219]
- Files:
-
- 22 added
- 2 deleted
- 41 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/io/http/worker.hfa
re874605 r93d2219 2 2 3 3 #include <iofwd.hfa> 4 #include < queueLockFree.hfa>4 #include <containers/lockfree.hfa> 5 5 #include <thread.hfa> 6 6 -
doc/theses/mike_brooks_MMath/programs/hello-md.cfa
re874605 r93d2219 1 1 #include "array.hfa" 2 3 4 trait ix( C &, E &, ztype(N) ) {5 E & ?[?]( C &, ptrdiff_t );6 void __taglen( tag(C), tag(N) );7 };8 9 forall( ztype(Zn), ztype(S), Timmed &, Tbase & )10 void __taglen( tag(arpk(Zn, S, Timmed, Tbase)), tag(Zn) ) {}11 2 12 3 … … 38 29 39 30 40 forall( ztype( N ) ) 31 32 33 34 35 36 37 38 39 40 forall( [N] ) 41 41 void print1d_cstyle( array(float, N) & c ); 42 42 43 forall( C &, ztype( N ) | ix( C, float, N ) )43 forall( [N], C & | ar( C, float, N ) ) 44 44 void print1d( C & c ); 45 45 … … 58 58 59 59 60 forall( ztype( N ))60 forall( [N] ) 61 61 void print1d_cstyle( array(float, N) & c ) { 62 for( i; z(N)) {62 for( i; N ) { 63 63 printf("%.1f ", c[i]); 64 64 } … … 78 78 79 79 80 forall( C &, ztype( N ) | ix( C, float, N ) )80 forall( [N], C & | ar( C, float, N ) ) 81 81 void print1d( C & c ) { 82 for( i; z(N)) {82 for( i; N ) { 83 83 printf("%.1f ", c[i]); 84 84 } … … 99 99 100 100 101 void fill( array(float, Z(5), Z(7)) & a ) {101 void fill( array(float, 5, 7) & a ) { 102 102 for ( i; (ptrdiff_t) 5 ) { 103 103 for ( j; 7 ) { 104 a[ [i,j]] = 1.0 * i + 0.1 * j;105 printf("%.1f ", a[ [i,j]]);104 a[i,j] = 1.0 * i + 0.1 * j; 105 printf("%.1f ", a[i,j]); 106 106 } 107 107 printf("\n"); … … 118 118 119 119 120 array( float, Z(5), Z(7)) a;120 array( float, 5, 7 ) a; 121 121 fill(a); 122 122 /* … … 148 148 149 149 150 print1d( a[ [ 2, all ]] ); // 2.0 2.1 2.2 2.3 2.4 2.5 2.6151 print1d( a[ [ all, 3 ]] ); // 0.3 1.3 2.3 3.3 4.3150 print1d( a[ 2, all ] ); // 2.0 2.1 2.2 2.3 2.4 2.5 2.6 151 print1d( a[ all, 3 ] ); // 0.3 1.3 2.3 3.3 4.3 152 152 153 153 154 154 155 print1d_cstyle( a[ [ 2, all ]] );155 print1d_cstyle( a[ 2, all ] ); 156 156 157 157 … … 161 161 162 162 163 #ifdef SHOW ERR1163 #ifdef SHOW_ERROR_1 164 164 165 print1d_cstyle( a[ [ all, 2 ]] ); // bad165 print1d_cstyle( a[ all, 2 ] ); // bad 166 166 167 167 #endif -
doc/theses/thierry_delisle_PhD/thesis/text/front.tex
re874605 r93d2219 161 161 Thanks to Andrew Beach, Michael Brooks, Colby Parsons, Mubeen Zulfiqar, Fangren Yu and Jiada Liang for their work on the \CFA project as well as all the discussions which have helped me concretize the ideas in this thesis. 162 162 163 Finally, I acknowledge that this has been possible thanks to the financial help offered by the David R. Cheriton School of Computer Science and the corporate partnership with Huawei Ltd.163 Finally, I acknowledge that this has been possible thanks to the financial help offered by the David R. Cheriton School of Computer Science, the corporate partnership with Huawei Ltd. and the Natural Sciences and Engineering Research Council. 164 164 \cleardoublepage 165 165 -
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 & ); -
src/AST/Type.cpp
re874605 r93d2219 147 147 // --- TypeInstType 148 148 149 bool TypeInstType::operator==( const TypeInstType & other ) const { 150 return base == other.base 151 && formal_usage == other.formal_usage 152 && expr_id == other.expr_id; 153 } 154 149 155 TypeInstType::TypeInstType( const TypeDecl * b, 150 156 CV::Qualifiers q, std::vector<ptr<Attribute>> && as ) … … 157 163 158 164 bool TypeInstType::isComplete() const { return base->sized; } 165 166 std::string TypeInstType::TypeEnvKey::typeString() const { 167 return std::string("_") + std::to_string(formal_usage) 168 + "_" + std::to_string(expr_id) + "_" + base->name; 169 } 170 171 bool TypeInstType::TypeEnvKey::operator==( 172 const TypeInstType::TypeEnvKey & other ) const { 173 return base == other.base 174 && formal_usage == other.formal_usage 175 && expr_id == other.expr_id; 176 } 177 178 bool TypeInstType::TypeEnvKey::operator<( 179 const TypeInstType::TypeEnvKey & other ) const { 180 // TypeEnvKey ordering is an arbitrary total ordering. 181 // It doesn't mean anything but allows for a sorting. 182 if ( base < other.base ) { 183 return true; 184 } else if ( other.base < base ) { 185 return false; 186 } else if ( formal_usage < other.formal_usage ) { 187 return true; 188 } else if ( other.formal_usage < formal_usage ) { 189 return false; 190 } else { 191 return expr_id < other.expr_id; 192 } 193 } 159 194 160 195 // --- TupleType -
src/AST/Type.hpp
re874605 r93d2219 408 408 409 409 TypeEnvKey() = default; 410 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0): base(base), formal_usage(formal_usage), expr_id(expr_id) {} 411 TypeEnvKey(const TypeInstType & inst): base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {} 412 std::string typeString() const { return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + base->name; } 413 bool operator==(const TypeEnvKey & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; } 410 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0) 411 : base(base), formal_usage(formal_usage), expr_id(expr_id) {} 412 TypeEnvKey(const TypeInstType & inst) 413 : base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {} 414 std::string typeString() const; 415 bool operator==(const TypeEnvKey & other) const; 416 bool operator<(const TypeEnvKey & other) const; 414 417 }; 415 418 416 bool operator==(const TypeInstType & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; }419 bool operator==(const TypeInstType & other) const; 417 420 418 421 TypeInstType( -
src/AST/module.mk
re874605 r93d2219 67 67 AST/Util.cpp \ 68 68 AST/Util.hpp \ 69 AST/Vector.hpp \ 69 70 AST/Visitor.hpp 70 71 -
src/GenPoly/GenPoly.cc
re874605 r93d2219 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 15:25:00 202213 // Update Count : 1 612 // Last Modified On : Mon Oct 24 15:19:00 2022 13 // Update Count : 17 14 14 // 15 15 … … 194 194 195 195 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 196 if ( typeVars.find( inst->typeString()) != typeVars.end() ) return type;196 if ( typeVars.find( *inst ) != typeVars.end() ) return type; 197 197 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 198 198 return isPolyType( array->base, subst ); … … 227 227 228 228 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) { 229 auto var = typeVars.find( inst->name);229 auto var = typeVars.find( *inst ); 230 230 if ( var != typeVars.end() && var->second.isComplete ) { 231 231 … … 784 784 785 785 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 786 typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) );786 typeVars.insert( *type, ast::TypeDecl::Data( type->base ) ); 787 787 } 788 788 … … 816 816 } 817 817 818 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ) {819 for ( auto const & pair : typeVars ) {820 os << pair.first << " (" << pair.second << ") ";821 } // for822 os << std::endl;823 }824 825 818 } // namespace GenPoly 826 819 -
src/GenPoly/GenPoly.h
re874605 r93d2219 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 15:06:00 202213 // Update Count : 912 // Last Modified On : Mon Oct 24 15:18:00 2022 13 // Update Count : 11 14 14 // 15 15 … … 22 22 #include "AST/Decl.hpp" // for TypeDecl::Data 23 23 #include "AST/Fwd.hpp" // for ApplicationExpr, BaseInstType, Func... 24 #include "AST/Type.hpp" // for TypeInstType::TypeEnvKey 24 25 #include "SymTab/Mangler.h" // for Mangler 25 26 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... … … 28 29 namespace GenPoly { 29 30 30 // TODO Via some tricks this works for ast::TypeDecl::Data as well.31 31 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 32 using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >;32 using TypeVarMap = ErasableScopedMap< ast::TypeInstType::TypeEnvKey, ast::TypeDecl::Data >; 33 33 34 34 /// Replaces a TypeInstType by its referrent in the environment, if applicable 35 35 Type* replaceTypeInst( Type* type, const TypeSubstitution* env ); 36 const ast::Type * replaceTypeInst( const ast::Type *, const ast::TypeSubstitution * ); 36 37 37 38 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided … … 53 54 /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters 54 55 ReferenceToType *isDynRet( FunctionType *function ); 56 const ast::BaseInstType *isDynRet( const ast::FunctionType * func ); 55 57 56 58 /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type … … 112 114 /// Prints type variable map 113 115 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 114 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars );115 116 116 117 /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType(). … … 128 129 /// Gets the name of the layout function for a given aggregate type, given its declaration 129 130 inline std::string layoutofName( AggregateDecl *decl ) { return std::string( "_layoutof_" ) + decl->get_name(); } 131 inline std::string layoutofName( ast::AggregateDecl const * decl ) { 132 return std::string( "_layoutof_" ) + decl->name; 133 } 130 134 131 135 } // namespace GenPoly -
src/GenPoly/InstantiateGenericNew.cpp
re874605 r93d2219 26 26 #include "AST/Pass.hpp" // for Pass, WithGuard, WithShortCi... 27 27 #include "AST/TranslationUnit.hpp" // for TranslationUnit 28 #include "AST/Vector.hpp" // for vector 28 29 #include "CodeGen/OperatorTable.h" // for isAssignment 29 30 #include "Common/ScopedMap.h" // for ScopedMap … … 39 40 // Utilities: 40 41 41 using type_vector = std::vector< ast::ptr< ast::TypeExpr >>;42 using type_vector = ast::vector< ast::TypeExpr >; 42 43 43 44 /// Abstracts type equality for a list of parameter types. 44 45 struct TypeList { 45 46 TypeList() : params() {} 46 TypeList( std::vector< ast::ptr< ast::Type >> const & params ) :47 TypeList( ast::vector< ast::Type > const & params ) : 47 48 params( params ) {} 48 TypeList( std::vector< ast::ptr< ast::Type >> && params ) :49 TypeList( ast::vector< ast::Type > && params ) : 49 50 params( std::move( params ) ) {} 50 51 TypeList( TypeList const & that ) : params( that.params ) {} 51 52 TypeList( TypeList && that ) : params( std::move( that.params ) ) {} 52 53 53 TypeList( std::vector< ast::ptr< ast::TypeExpr >> const & exprs ) :54 TypeList( ast::vector< ast::TypeExpr > const & exprs ) : 54 55 params() { 55 56 for ( auto expr : exprs ) { … … 82 83 } 83 84 84 std::vector<ast::ptr<ast::Type>> params;85 ast::vector<ast::Type> params; 85 86 }; 86 87 … … 103 104 /// returns null if no such value exists. 104 105 ast::AggregateDecl const * lookup( 105 ast::AggregateDecl const * key, type_vector const & params ) const { 106 ast::AggregateDecl const * key, 107 type_vector const & params ) const { 106 108 // This type repackaging is used for the helpers. 107 109 ast::ptr<ast::AggregateDecl> ptr = key; … … 150 152 } 151 153 152 bool isDtypeStatic( std::vector<ast::ptr<ast::TypeDecl>> const & baseParams ) {154 bool isDtypeStatic( ast::vector<ast::TypeDecl> const & baseParams ) { 153 155 return std::all_of( baseParams.begin(), baseParams.end(), 154 156 []( ast::TypeDecl const * td ){ return !td->isComplete(); } … … 161 163 /// least one parameter type, and dynamic if there is no concrete instantiation. 162 164 GenericType makeSubstitutions( 163 std::vector<ast::ptr<ast::TypeExpr>> & out,164 std::vector<ast::ptr<ast::TypeDecl>> const & baseParams,165 std::vector<ast::ptr<ast::Expr>> const & params ) {165 ast::vector<ast::TypeExpr> & out, 166 ast::vector<ast::TypeDecl> const & baseParams, 167 ast::vector<ast::Expr> const & params ) { 166 168 GenericType gt = GenericType::dtypeStatic; 167 169 … … 214 216 /// Substitutes types of members according to baseParams => typeSubs, 215 217 /// returning the result in a new vector. 216 std::vector<ast::ptr<ast::Decl>> substituteMembers(217 std::vector<ast::ptr<ast::Decl>> const & members,218 std::vector<ast::ptr<ast::TypeDecl>> const & baseParams,219 std::vector<ast::ptr<ast::TypeExpr>> const & typeSubs ) {220 std::vector<ast::ptr<ast::Decl>> out;218 ast::vector<ast::Decl> substituteMembers( 219 ast::vector<ast::Decl> const & members, 220 ast::vector<ast::TypeDecl> const & baseParams, 221 ast::vector<ast::TypeExpr> const & typeSubs ) { 222 ast::vector<ast::Decl> out; 221 223 ast::TypeSubstitution subs( baseParams, typeSubs ); 222 224 for ( ast::ptr<ast::Decl> const & member : members ) { … … 235 237 /// modifying them in-place. 236 238 void substituteMembersHere( 237 std::vector<ast::ptr<ast::Decl>> & members,238 std::vector<ast::ptr<ast::TypeDecl>> const & baseParams,239 std::vector<ast::ptr<ast::TypeExpr>> const & typeSubs ) {239 ast::vector<ast::Decl> & members, 240 ast::vector<ast::TypeDecl> const & baseParams, 241 ast::vector<ast::TypeExpr> const & typeSubs ) { 240 242 ast::TypeSubstitution subs( baseParams, typeSubs ); 241 243 for ( ast::ptr<ast::Decl> & member : members ) { … … 285 287 286 288 ast::Expr const * fixMemberExpr( 287 std::vector<ast::ptr<ast::TypeDecl>> const & baseParams,289 ast::vector<ast::TypeDecl> const & baseParams, 288 290 ast::MemberExpr const * memberExpr ); 289 291 … … 349 351 350 352 ast::Expr const * FixDtypeStatic::fixMemberExpr( 351 std::vector<ast::ptr<ast::TypeDecl>> const & baseParams,353 ast::vector<ast::TypeDecl> const & baseParams, 352 354 ast::MemberExpr const * memberExpr ) { 353 355 // Need to cast dtype-static member expressions to their actual type … … 461 463 type_vector const & typeSubs, ast::UnionDecl const * decl ); 462 464 463 void replaceParametersWithConcrete( std::vector<ast::ptr<ast::Expr>> & params );465 void replaceParametersWithConcrete( ast::vector<ast::Expr> & params ); 464 466 ast::Type const * replaceWithConcrete( ast::Type const * type, bool doClone ); 465 467 … … 470 472 /// marks it as stripped. 471 473 void stripDtypeParams( ast::AggregateDecl * base, 472 std::vector<ast::ptr<ast::TypeDecl>> & baseParams,473 std::vector<ast::ptr<ast::TypeExpr>> const & typeSubs );474 ast::vector<ast::TypeDecl> & baseParams, 475 ast::vector<ast::TypeExpr> const & typeSubs ); 474 476 }; 475 477 … … 511 513 // and put substitutions in typeSubs. 512 514 assertf( inst->base, "Base data-type has parameters." ); 513 std::vector<ast::ptr<ast::TypeExpr>> typeSubs;515 ast::vector<ast::TypeExpr> typeSubs; 514 516 GenericType gt = makeSubstitutions( typeSubs, inst->base->params, inst->params ); 515 517 switch ( gt ) { … … 570 572 ast::AggregateDecl const * aggr = 571 573 expr->aggregate->result.strict_as<ast::BaseInstType>()->aggr(); 572 std::vector<ast::ptr<ast::Decl>> const & members = aggr->members;574 ast::vector<ast::Decl> const & members = aggr->members; 573 575 auto it = std::find( members.begin(), members.end(), expr->member ); 574 576 memberIndex = std::distance( members.begin(), it ); … … 643 645 644 646 void GenericInstantiator::replaceParametersWithConcrete( 645 std::vector<ast::ptr<ast::Expr>> & params ) {647 ast::vector<ast::Expr> & params ) { 646 648 for ( ast::ptr<ast::Expr> & param : params ) { 647 649 auto paramType = param.as<ast::TypeExpr>(); … … 673 675 void GenericInstantiator::stripDtypeParams( 674 676 ast::AggregateDecl * base, 675 std::vector<ast::ptr<ast::TypeDecl>> & baseParams,676 std::vector<ast::ptr<ast::TypeExpr>> const & typeSubs ) {677 ast::vector<ast::TypeDecl> & baseParams, 678 ast::vector<ast::TypeExpr> const & typeSubs ) { 677 679 substituteMembersHere( base->members, baseParams, typeSubs ); 678 680 -
src/GenPoly/ScrubTyVars.cc
re874605 r93d2219 20 20 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 21 21 #include "ScrubTyVars.h" 22 #include "SymTab/Mangler.h" // for mangle , typeMode22 #include "SymTab/Mangler.h" // for mangleType 23 23 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Typ... 24 24 #include "SynTree/Expression.h" // for Expression (ptr only), NameExpr … … 195 195 } 196 196 197 auto typeVar = typeVars->find( type->name );197 auto typeVar = typeVars->find( *type ); 198 198 if ( typeVar == typeVars->end() ) { 199 199 return type; … … 227 227 if ( dynType ) { 228 228 return new ast::NameExpr( expr->location, 229 sizeofName( Mangle::mangle ( dynType, Mangle::typeMode()) ) );229 sizeofName( Mangle::mangleType( dynType ) ) ); 230 230 } else { 231 231 return expr; … … 237 237 if ( dynType ) { 238 238 return new ast::NameExpr( expr->location, 239 alignofName( Mangle::mangle ( dynType, Mangle::typeMode()) ) );239 alignofName( Mangle::mangleType( dynType ) ) ); 240 240 } else { 241 241 return expr; -
src/Parser/ParseNode.h
re874605 r93d2219 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Oct 18 1 4:15:37202213 // Update Count : 93 612 // Last Modified On : Tue Oct 18 16:22:15 2022 13 // Update Count : 937 14 14 // 15 15 … … 468 468 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr 469 469 if ( ! cur && temp ) { // non-homogeneous nodes ? 470 SemanticError( cur->location, "internal error, non-homogeneous nodes founds in buildList processing." );470 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 471 471 } // if 472 472 } // while -
src/ResolvExpr/SatisfyAssertions.cpp
re874605 r93d2219 268 268 ast::ptr< ast::Type > resType = cand.expr->result; 269 269 cand.env.apply( resType ); 270 return Mangle::mangle ( resType, Mangle::typeMode());270 return Mangle::mangleType( resType ); 271 271 } 272 272 -
src/SymTab/Mangler.cc
re874605 r93d2219 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:40:29 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jan 11 21:56:06 202113 // Update Count : 7 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 21 16:18:00 2022 13 // Update Count : 75 14 14 // 15 15 #include "Mangler.h" … … 418 418 void postvisit( const ast::QualifiedType * qualType ); 419 419 420 std::string get_mangleName() { return mangleName; } 420 /// The result is the current constructed mangled name. 421 std::string result() const { return mangleName; } 421 422 private: 422 423 std::string mangleName; ///< Mangled name being constructed … … 444 445 } // namespace 445 446 446 447 447 std::string mangle( const ast::Node * decl, Mangle::Mode mode ) { 448 ast::Pass<Mangler_new> mangler( mode ); 449 maybeAccept( decl, mangler ); 450 return mangler.core.get_mangleName(); 448 return ast::Pass<Mangler_new>::read( decl, mode ); 451 449 } 452 450 … … 689 687 } // for 690 688 for ( auto & assert : ptype->assertions ) { 691 ast::Pass<Mangler_new> sub_mangler( 692 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 693 assert->var->accept( sub_mangler ); 694 assertionNames.push_back( sub_mangler.core.get_mangleName() ); 689 assertionNames.push_back( ast::Pass<Mangler_new>::read( 690 assert->var.get(), 691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); 695 692 acount++; 696 693 } // for -
src/SymTab/Mangler.h
re874605 r93d2219 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:44:03 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:45:30 201713 // Update Count : 1 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Oct 27 11:58:00 2022 13 // Update Count : 16 14 14 // 15 15 … … 22 22 23 23 #include "AST/Bitfield.hpp" 24 #include "AST/Fwd.hpp"25 24 #include "SynTree/SynTree.h" // for Types 26 25 #include "SynTree/Visitor.h" // for Visitor, maybeAccept … … 33 32 // * Currently name compression is not implemented. 34 33 34 namespace ast { 35 class Node; 36 } 35 37 namespace ResolvExpr { 36 38 class TypeEnvironment; … … 101 103 using Mode = bitfield<mangle_flags>; 102 104 103 static inline Mode typeMode() { return NoOverrideable | Type; } 105 /// Mangle declaration name. 106 std::string mangle( const ast::Node * decl, Mode mode = {} ); 104 107 105 /// Mangle declaration name 106 std::string mangle( const ast::Node * decl, Mode mode = {} ); 108 /// Most common mangle configuration for types. 109 static inline std::string mangleType( const ast::Node * type ) { 110 return mangle( type, { NoOverrideable | Type } ); 111 } 107 112 108 113 namespace Encoding { -
src/SynTree/AddressExpr.cc
re874605 r93d2219 50 50 set_result( addrType( refType->base ) ); 51 51 } else { 52 if(!arg->result->location.isSet()) arg->result->location = arg->location; 52 53 SemanticError( arg->result, "Attempt to take address of non-lvalue expression: " ); 53 54 } // if -
src/Virtual/ExpandCasts.cc
re874605 r93d2219 295 295 // returns the previous declaration for error messages. 296 296 ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) { 297 std::string const & mangledName = 298 Mangle::mangle( typeIdDecl->type, Mangle::typeMode() ); 297 std::string mangledName = Mangle::mangleType( typeIdDecl->type ); 299 298 ast::ObjectDecl const *& value = instances[ mangledName ]; 300 299 if ( value ) { … … 310 309 311 310 ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) { 312 std::string const & mangledName = 313 Mangle::mangle( typeIdType, Mangle::typeMode() ); 311 std::string mangledName = Mangle::mangleType( typeIdType ); 314 312 auto const it = instances.find( mangledName ); 315 313 return ( instances.end() == it ) ? nullptr : it->second; -
tests/array-container/array-basic.cfa
re874605 r93d2219 78 78 } 79 79 80 forall( A & | ar(A, float) )80 forall( [N], A & | ar(A, float, N) ) 81 81 float total1d_hi( A & a ) { 82 82 float total = 0.0f; 83 for (i; a`len)83 for (i; N) 84 84 total += a[i]; 85 85 return total; -
tests/collections/atomic_mpsc.cfa
re874605 r93d2219 1 1 #include <fstream.hfa> 2 #include < queueLockFree.hfa>2 #include <containers/lockfree.hfa> 3 3 #include <thread.hfa> 4 4 -
tests/configs/parsebools.cfa
re874605 r93d2219 15 15 // 16 16 17 #include <parseargs.hfa>18 17 #include <fstream.hfa> 19 18 20 19 #include "../meta/fork+exec.hfa" 20 21 // last as a work around to a parse bug 22 #include <parseargs.hfa> 21 23 22 24 int main(int argc, char * argv[]) { … … 30 32 bool sf = true; 31 33 32 cfa_option options[] = { 33 {'e', "yesno", "test yes/no", YN, parse_yesno}, 34 {'y', "YN", "test yes/no", Yn, parse_yesno}, 35 {'n', "yn", "test yes/no", yn, parse_yesno}, 36 {'t', "truefalse", "test true/false", tf, parse_truefalse}, 37 {'s', "settrue", "test set true", st, parse_settrue}, 38 {'u', "setfalse", "test set false", sf, parse_setfalse}, 39 }; 40 int options_cnt = sizeof(options) / sizeof(cfa_option); 34 array( cfa_option, 6 ) options; 35 options[0] = (cfa_option){'e', "yesno", "test yes/no", YN, parse_yesno}; 36 options[1] = (cfa_option){'y', "YN", "test yes/no", Yn, parse_yesno}; 37 options[2] = (cfa_option){'n', "yn", "test yes/no", yn, parse_yesno}; 38 options[3] = (cfa_option){'t', "truefalse", "test true/false", tf, parse_truefalse}; 39 options[4] = (cfa_option){'s', "settrue", "test set true", st, parse_settrue}; 40 options[5] = (cfa_option){'u', "setfalse", "test set false", sf, parse_setfalse}; 41 41 42 42 char **left; 43 parse_args( options, options_cnt,"[OPTIONS]...\ntesting bool parameters", left);43 parse_args( options, "[OPTIONS]...\ntesting bool parameters", left); 44 44 45 45 sout | "yes/no :" | YN; -
tests/configs/parsenums.cfa
re874605 r93d2219 15 15 // 16 16 17 #include <fstream.hfa> 18 19 #include "../meta/fork+exec.hfa" 20 21 // last as workaround to parser bug 17 22 #include <parseargs.hfa> 18 #include <fstream.hfa>19 20 #include "../meta/fork+exec.hfa"21 23 22 24 #if __SIZEOF_LONG__ == 4 … … 42 44 43 45 44 cfa_option options[] = { 45 { 'i', "int", "test int", i }, 46 { 'u', "unsigned", "test unsigned", u }, 47 { 'l', "unsignedlong", "test unsigned long", ul }, 48 { 'L', "unsignedlonglong", "test unsigned long long", ull }, 49 { 'd', "double", "test double", d }, 50 }; 51 int options_cnt = sizeof(options) / sizeof(cfa_option); 46 array( cfa_option, 5 ) options; 47 options[0] = (cfa_option){ 'i', "int", "test int", i }; 48 options[1] = (cfa_option){ 'u', "unsigned", "test unsigned", u }; 49 options[2] = (cfa_option){ 'l', "unsignedlong", "test unsigned long", ul }; 50 options[3] = (cfa_option){ 'L', "unsignedlonglong", "test unsigned long long", ull }; 51 options[4] = (cfa_option){ 'd', "double", "test double", d }; 52 52 53 53 char **left; 54 parse_args( options, options_cnt,"[OPTIONS]...\ntesting bool parameters", left);54 parse_args( options, "[OPTIONS]...\ntesting bool parameters", left); 55 55 56 56 sout | "int :" | i; -
tests/configs/usage.cfa
re874605 r93d2219 15 15 // 16 16 17 #include <fstream.hfa> 18 #include "../meta/fork+exec.hfa" 17 19 #include <parseargs.hfa> 18 #include <fstream.hfa>19 20 20 #include "../meta/fork+exec.hfa"21 21 22 22 int main() { … … 25 25 sout | "No args, no errors"; 26 26 if(pid_t child = strict_fork(); child == 0) { 27 cfa_option opts[0];28 print_args_usage(1, fake_argv, opts, 0,"Test usage", false);27 array( cfa_option, 0 ) opts; 28 print_args_usage(1, fake_argv, opts, "Test usage", false); 29 29 } 30 30 else { … … 35 35 sout | "No args, with errors"; 36 36 if(pid_t child = strict_fork(); child == 0) { 37 cfa_option opts[0];38 print_args_usage(1, fake_argv, opts, 0,"Test usage", true);37 array( cfa_option, 0 ) opts; 38 print_args_usage(1, fake_argv, opts, "Test usage", true); 39 39 } 40 40 else { … … 46 46 if(pid_t child = strict_fork(); child == 0) { 47 47 int a, b, c; 48 cfa_option opts[] = { 49 {'a', "", "First arg", a }, 50 {'b', "", "Second arg", b }, 51 {'c', "", "Third arg", c }, 52 }; 53 print_args_usage(1, fake_argv, opts, 3, "Test usage", false); 48 array( cfa_option, 3 ) opts; 49 opts[0] = (cfa_option){'a', "", "First arg", a }; 50 opts[1] = (cfa_option){'b', "", "Second arg", b }; 51 opts[2] = (cfa_option){'c', "", "Third arg", c }; 52 print_args_usage(1, fake_argv, opts, "Test usage", false); 54 53 } 55 54 else { … … 61 60 if(pid_t child = strict_fork(); child == 0) { 62 61 int a, b, c; 63 cfa_option opts[] = { 64 {'\0', "AA", "First arg", a }, 65 {'\0', "BB", "Second arg", b }, 66 {'\0', "CC", "Third arg", c }, 67 }; 68 print_args_usage(1, fake_argv, opts, 3, "Test usage", false); 62 array( cfa_option, 3 ) opts; 63 opts[0] = (cfa_option){'\0', "AA", "First arg", a }; 64 opts[1] = (cfa_option){'\0', "BB", "Second arg", b }; 65 opts[2] = (cfa_option){'\0', "CC", "Third arg", c }; 66 print_args_usage(1, fake_argv, opts, "Test usage", false); 69 67 } 70 68 else { … … 76 74 if(pid_t child = strict_fork(); child == 0) { 77 75 int a, b, c; 78 cfa_option opts[] = { 79 {'a', "", "First arg", a }, 80 {'b', "BBBB", "Second arg", b }, 81 {'\0', "CC", "Third arg", c }, 82 }; 83 print_args_usage(1, fake_argv, opts, 3, "Test usage", false); 76 array( cfa_option, 3 ) opts; 77 opts[0] = (cfa_option){'a', "", "First arg", a }; 78 opts[1] = (cfa_option){'b', "BBBB", "Second arg", b }; 79 opts[2] = (cfa_option){'\0', "CC", "Third arg", c }; 80 print_args_usage(1, fake_argv, opts, "Test usage", false); 84 81 } 85 82 else { … … 91 88 if(pid_t child = strict_fork(); child == 0) { 92 89 int a, b, c; 93 cfa_option opts[] = { 94 {'a', "", "First arg", a }, 95 {'b', "BBBB", "", b }, 96 {'\0', "CC", "Third arg", c }, 97 }; 98 print_args_usage(1, fake_argv, opts, 3, "Test usage", false); 90 array( cfa_option, 3 ) opts; 91 opts[0] = (cfa_option){'a', "", "First arg", a }; 92 opts[1] = (cfa_option){'b', "BBBB", "", b }; 93 opts[2] = (cfa_option){'\0', "CC", "Third arg", c }; 94 print_args_usage(1, fake_argv, opts, "Test usage", false); 99 95 } 100 96 else { … … 106 102 if(pid_t child = strict_fork(); child == 0) { 107 103 int a, b, c; 108 cfa_option opts[] = { 109 {'a', "", "First arg\nThe description has multiple lines,\n...for some reason", a }, 110 {'b', "BBBB", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", b }, 111 {'\0', "CC", "Third arg", c }, 112 }; 113 print_args_usage(1, fake_argv, opts, 3, "Test usage", false); 104 array( cfa_option, 3 ) opts; 105 opts[0] = (cfa_option){'a', "", "First arg\nThe description has multiple lines,\n...for some reason", a }; 106 opts[1] = (cfa_option){'b', "BBBB", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", b }; 107 opts[2] = (cfa_option){'\0', "CC", "Third arg", c }; 108 print_args_usage(1, fake_argv, opts, "Test usage", false); 114 109 } 115 110 else { -
tests/device/cpu.cfa
re874605 r93d2219 117 117 unsigned find_idx() { 118 118 int idxs = count_cache_indexes(); 119 if( 0 == idxs ) return 0; 119 120 120 121 unsigned found_level = 0; … … 179 180 unsigned idx = find_idx(); 180 181 // For all procs check mapping is consistent 181 for(cpu_me; cpu_info.hthrd_count) {182 if( idx > 0 ) for(cpu_me; cpu_info.hthrd_count) { 182 183 char buf_me[32]; 183 184 size_t len_me = read_cpuidxinfo_into(cpu_me, idx, "shared_cpu_list", buf_me, 32);
Note: See TracChangeset
for help on using the changeset viewer.