Changes in / [2b22e050:1dbc8590]
- Location:
- src
- Files:
-
- 10 edited
-
benchmark/Makefile.am (modified) (1 diff)
-
benchmark/Makefile.in (modified) (1 diff)
-
libcfa/bits/containers.h (modified) (2 diffs)
-
libcfa/concurrency/invoke.h (modified) (2 diffs)
-
libcfa/concurrency/kernel (modified) (4 diffs)
-
libcfa/concurrency/kernel.c (modified) (11 diffs)
-
libcfa/concurrency/kernel_private.h (modified) (1 diff)
-
libcfa/concurrency/preemption.c (modified) (1 diff)
-
libcfa/concurrency/thread.c (modified) (2 diffs)
-
libcfa/interpose.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/benchmark/Makefile.am
r2b22e050 r1dbc8590 43 43 44 44 %.runquiet : 45 @+make $(basename $@) CFLAGS="-w"45 @+make $(basename $@) 46 46 @taskset -c 1 ./a.out 47 47 @rm -f a.out -
src/benchmark/Makefile.in
r2b22e050 r1dbc8590 459 459 460 460 %.runquiet : 461 @+make $(basename $@) CFLAGS="-w"461 @+make $(basename $@) 462 462 @taskset -c 1 ./a.out 463 463 @rm -f a.out -
src/libcfa/bits/containers.h
r2b22e050 r1dbc8590 191 191 //----------------------------------------------------------------------------- 192 192 #ifdef __cforall 193 forall(dtype TYPE | sized(TYPE)) 193 trait is_db_node(dtype T) { 194 T*& get_next( T& ); 195 T*& get_prev( T& ); 196 }; 197 #endif 198 199 #ifdef __cforall 200 forall(dtype TYPE | is_db_node(TYPE)) 194 201 #define T TYPE 195 #define __getter_t * [T * & next, T * & prev] ( T & ) 196 #else 197 typedef void (*__generit_c_getter_t)(); 198 #define T void 199 #define __getter_t __generit_c_getter_t 202 #else 203 #define T void 200 204 #endif 201 205 struct __dllist { 202 206 T * head; 203 __getter_t __get; 204 }; 205 #undef T 206 #undef __getter_t 207 }; 208 #undef T 207 209 208 210 #ifdef __cforall … … 214 216 #ifdef __cforall 215 217 216 forall(dtype T | sized(T)) 217 static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) { 218 this.head{ NULL }; 219 this.__get = __get; 220 } 221 222 #define _next .0 223 #define _prev .1 224 forall(dtype T | sized(T)) 225 static inline void push_front( __dllist(T) & this, T & node ) with( this ) { 226 if ( head ) { 227 __get( node )_next = head; 228 __get( node )_prev = __get( *head )_prev; 229 // inserted node must be consistent before it is seen 230 // prevent code movement across barrier 231 asm( "" : : : "memory" ); 232 __get( *head )_prev = &node; 233 T & prev = *__get( node )_prev; 234 __get( prev )_next = &node; 235 } 236 else { 237 __get( node )_next = &node; 238 __get( node )_prev = &node; 239 } 240 241 // prevent code movement across barrier 242 asm( "" : : : "memory" ); 243 head = &node; 244 } 245 246 forall(dtype T | sized(T)) 247 static inline void remove( __dllist(T) & this, T & node ) with( this ) { 248 if ( &node == head ) { 249 if ( __get( *head )_next == head ) { 250 head = NULL; 251 } 252 else { 253 head = __get( *head )_next; 254 } 255 } 256 __get( *__get( node )_next )_prev = __get( node )_prev; 257 __get( *__get( node )_prev )_next = __get( node )_next; 258 __get( node )_next = NULL; 259 __get( node )_prev = NULL; 260 } 261 #undef _next 262 #undef _prev 218 forall(dtype T | is_db_node(T)) 219 static inline void ?{}( __dllist(T) & this ) with( this ) { 220 head{ NULL }; 221 } 222 223 // forall(dtype T | is_db_node(T) | sized(T)) 224 // static inline void push_front( __dllist(T) & this, T & node ) with( this ) { 225 // if ( head ) { 226 // get_next( node ) = head; 227 // get_prev( node ) = get_prev( *head ); 228 // // inserted node must be consistent before it is seen 229 // // prevent code movement across barrier 230 // asm( "" : : : "memory" ); 231 // get_prev( *head ) = node; 232 // T & prev = *get_prev( node ); 233 // get_next( prev ) = node; 234 // } 235 // else { 236 // get_next( node ) = &node; 237 // get_prev( node ) = &node; 238 // } 239 240 // // prevent code movement across barrier 241 // asm( "" : : : "memory" ); 242 // head = val; 243 // } 244 245 // forall(dtype T | is_db_node(T) | sized(T)) 246 // static inline T * remove( __dllist(T) & this, T & node ) with( this ) { 247 // if ( &node == head ) { 248 // if ( get_next( *head ) == head ) { 249 // head = NULL; 250 // } 251 // else { 252 // head = get_next( *head ); 253 // } 254 // } 255 // get_prev( *get_next( node ) ) = get_prev( node ); 256 // get_next( *get_prev( node ) ) = get_next( node ); 257 // get_next( node ) = NULL; 258 // get_prev( node ) = NULL; 259 // } 263 260 #endif 264 261 -
src/libcfa/concurrency/invoke.h
r2b22e050 r1dbc8590 136 136 struct thread_desc * next; 137 137 138 struct { 139 struct thread_desc * next; 140 struct thread_desc * prev; 141 } node; 138 __cfaabi_dbg_debug_do( 139 // instrusive link field for debugging 140 struct thread_desc * dbg_next; 141 struct thread_desc * dbg_prev; 142 ) 142 143 }; 143 144 … … 146 147 static inline thread_desc * & get_next( thread_desc & this ) { 147 148 return this.next; 148 }149 150 static inline [thread_desc *&, thread_desc *& ] __get( thread_desc & this ) {151 return this.node.[next, prev];152 149 } 153 150 -
src/libcfa/concurrency/kernel
r2b22e050 r1dbc8590 40 40 41 41 //----------------------------------------------------------------------------- 42 // Cluster 43 struct cluster { 44 // Ready queue locks 45 __spinlock_t ready_queue_lock; 46 47 // Ready queue for threads 48 __queue_t(thread_desc) ready_queue; 49 50 // Name of the cluster 51 const char * name; 52 53 // Preemption rate on this cluster 54 Duration preemption_rate; 55 56 // List of idle processors 57 // __dllist_t(struct processor) idles; 58 }; 59 60 extern struct cluster * mainCluster; 61 extern Duration default_preemption(); 62 63 void ?{} (cluster & this, const char * name, Duration preemption_rate); 64 void ^?{}(cluster & this); 65 66 static inline void ?{} (cluster & this) { this{"Anonymous Cluster", default_preemption()}; } 67 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; } 68 static inline void ?{} (cluster & this, const char * name) { this{name, default_preemption()}; } 69 70 //----------------------------------------------------------------------------- 42 71 // Processor 43 extern struct cluster * mainCluster;44 45 72 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule }; 46 73 … … 74 101 75 102 // Cluster from which to get threads 76 structcluster * cltr;103 cluster * cltr; 77 104 78 105 // Name of the processor … … 100 127 bool pending_preemption; 101 128 102 // Idle lock103 104 // Link lists fields105 129 struct { 106 struct processor * next;107 struct processor * prev;108 } node;130 pthread_mutex_t lock; 131 pthread_cond_t cond; 132 } idle; 109 133 110 134 #ifdef __CFA_DEBUG__ … … 114 138 }; 115 139 116 void ?{}(processor & this, const char * name, structcluster & cltr);140 void ?{}(processor & this, const char * name, cluster & cltr); 117 141 void ^?{}(processor & this); 118 142 119 143 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster}; } 120 static inline void ?{}(processor & this, structcluster & cltr) { this{ "Anonymous Processor", cltr}; }144 static inline void ?{}(processor & this, cluster & cltr) { this{ "Anonymous Processor", cltr}; } 121 145 static inline void ?{}(processor & this, const char * name) { this{name, *mainCluster }; } 122 123 static inline [processor *&, processor *& ] __get( processor & this ) {124 return this.node.[next, prev];125 }126 127 //-----------------------------------------------------------------------------128 // Cluster129 struct cluster {130 // Ready queue locks131 __spinlock_t ready_queue_lock;132 133 // Ready queue for threads134 __queue_t(thread_desc) ready_queue;135 136 // Name of the cluster137 const char * name;138 139 // Preemption rate on this cluster140 Duration preemption_rate;141 142 // List of processors143 __spinlock_t proc_list_lock;144 __dllist_t(struct processor) procs;145 __dllist_t(struct processor) idles;146 147 // Link lists fields148 struct {149 cluster * next;150 cluster * prev;151 } node;152 };153 extern Duration default_preemption();154 155 void ?{} (cluster & this, const char * name, Duration preemption_rate);156 void ^?{}(cluster & this);157 158 static inline void ?{} (cluster & this) { this{"Anonymous Cluster", default_preemption()}; }159 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }160 static inline void ?{} (cluster & this, const char * name) { this{name, default_preemption()}; }161 162 static inline [cluster *&, cluster *& ] __get( cluster & this ) {163 return this.node.[next, prev];164 }165 146 166 147 // Local Variables: // -
src/libcfa/concurrency/kernel.c
r2b22e050 r1dbc8590 49 49 thread_desc * mainThread; 50 50 51 struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ;52 struct { __dllist_t(cluster ) list; __spinlock_t lock; } global_clusters;53 54 51 //----------------------------------------------------------------------------- 55 52 // Global state … … 120 117 self_mon_p = &self_mon; 121 118 next = NULL; 122 123 node.next = NULL; 124 node.prev = NULL; 125 doregister(this); 119 __cfaabi_dbg_debug_do( 120 dbg_next = NULL; 121 dbg_prev = NULL; 122 __cfaabi_dbg_thread_register(&this); 123 ) 126 124 127 125 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 169 167 ready_queue{}; 170 168 ready_queue_lock{}; 171 172 procs{ __get };173 idles{ __get };174 175 doregister(this);176 169 } 177 170 178 171 void ^?{}(cluster & this) { 179 unregister(this); 172 180 173 } 181 174 … … 189 182 190 183 __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this); 191 192 doregister(this->cltr, this);193 184 194 185 { … … 224 215 __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this); 225 216 } 226 227 unregister(this->cltr, this);228 217 229 218 V( this->terminated ); … … 523 512 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 524 513 525 global_threads. list{ __get };526 global_threads. lock{};527 global_clusters.list{ __get };528 global_clusters.lock{};529 530 514 // Initialize the main cluster 531 515 mainCluster = (cluster *)&storage_mainCluster; … … 655 639 656 640 static __spinlock_t kernel_abort_lock; 641 static __spinlock_t kernel_debug_lock; 657 642 static bool kernel_abort_called = false; 658 643 … … 663 648 664 649 // first task to abort ? 665 if ( kernel_abort_called ) { // not first task to abort ? 650 if ( ! kernel_abort_called ) { // not first task to abort ? 651 kernel_abort_called = true; 652 unlock( kernel_abort_lock ); 653 } 654 else { 666 655 unlock( kernel_abort_lock ); 667 656 668 657 sigset_t mask; 669 658 sigemptyset( &mask ); 670 sigaddset( &mask, SIGALRM ); // block SIGALRM signals 671 sigsuspend( &mask ); // block the processor to prevent further damage during abort 672 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 673 } 674 else { 675 kernel_abort_called = true; 676 unlock( kernel_abort_lock ); 659 sigaddset( &mask, SIGALRM ); // block SIGALRM signals 660 sigaddset( &mask, SIGUSR1 ); // block SIGUSR1 signals 661 sigsuspend( &mask ); // block the processor to prevent further damage during abort 662 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 677 663 } 678 664 … … 683 669 thread_desc * thrd = kernel_data; 684 670 685 if(thrd) { 686 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd ); 671 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd ); 672 __cfaabi_dbg_bits_write( abort_text, len ); 673 674 if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) { 675 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine ); 687 676 __cfaabi_dbg_bits_write( abort_text, len ); 688 689 if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {690 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );691 __cfaabi_dbg_bits_write( abort_text, len );692 }693 else {694 __cfaabi_dbg_bits_write( ".\n", 2 );695 }696 677 } 697 678 else { 698 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n");679 __cfaabi_dbg_bits_write( ".\n", 2 ); 699 680 } 700 681 } … … 703 684 return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2; 704 685 } 705 706 static __spinlock_t kernel_debug_lock;707 686 708 687 extern "C" { … … 759 738 760 739 //----------------------------------------------------------------------------- 761 // Global Queues762 void doregister( thread_desc & thrd ) {763 // lock ( global_thread.lock );764 // push_front( global_thread.list, thrd );765 // unlock ( global_thread.lock );766 }767 768 void unregister( thread_desc & thrd ) {769 // lock ( global_thread.lock );770 // remove( global_thread.list, thrd );771 // unlock( global_thread.lock );772 }773 774 void doregister( cluster & cltr ) {775 // lock ( global_cluster.lock );776 // push_front( global_cluster.list, cltr );777 // unlock ( global_cluster.lock );778 }779 780 void unregister( cluster & cltr ) {781 // lock ( global_cluster.lock );782 // remove( global_cluster.list, cltr );783 // unlock( global_cluster.lock );784 }785 786 787 void doregister( cluster * cltr, processor * proc ) {788 // lock (cltr->proc_list_lock __cfaabi_dbg_ctx2);789 // push_front(cltr->procs, *proc);790 // unlock (cltr->proc_list_lock);791 }792 793 void unregister( cluster * cltr, processor * proc ) {794 // lock (cltr->proc_list_lock __cfaabi_dbg_ctx2);795 // remove(cltr->procs, *proc );796 // unlock(cltr->proc_list_lock);797 }798 799 //-----------------------------------------------------------------------------800 740 // Debug 801 741 __cfaabi_dbg_debug_do( 742 struct { 743 thread_desc * tail; 744 } __cfaabi_dbg_thread_list = { NULL }; 745 746 void __cfaabi_dbg_thread_register( thread_desc * thrd ) { 747 if( !__cfaabi_dbg_thread_list.tail ) { 748 __cfaabi_dbg_thread_list.tail = thrd; 749 return; 750 } 751 __cfaabi_dbg_thread_list.tail->dbg_next = thrd; 752 thrd->dbg_prev = __cfaabi_dbg_thread_list.tail; 753 __cfaabi_dbg_thread_list.tail = thrd; 754 } 755 756 void __cfaabi_dbg_thread_unregister( thread_desc * thrd ) { 757 thread_desc * prev = thrd->dbg_prev; 758 thread_desc * next = thrd->dbg_next; 759 760 if( next ) { next->dbg_prev = prev; } 761 else { 762 assert( __cfaabi_dbg_thread_list.tail == thrd ); 763 __cfaabi_dbg_thread_list.tail = prev; 764 } 765 766 if( prev ) { prev->dbg_next = next; } 767 768 thrd->dbg_prev = NULL; 769 thrd->dbg_next = NULL; 770 } 771 802 772 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) { 803 773 this.prev_name = prev_name; -
src/libcfa/concurrency/kernel_private.h
r2b22e050 r1dbc8590 100 100 #define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)] 101 101 102 103 void doregister( struct thread_desc & thrd );104 void unregister( struct thread_desc & thrd );105 106 void doregister( struct cluster & cltr );107 void unregister( struct cluster & cltr );108 109 void doregister( struct cluster * cltr, struct processor * proc );110 void unregister( struct cluster * cltr, struct processor * proc );111 112 102 // Local Variables: // 113 103 // mode: c // -
src/libcfa/concurrency/preemption.c
r2b22e050 r1dbc8590 357 357 // Block sigalrms to control when they arrive 358 358 sigset_t mask; 359 sigfillset(&mask); 359 sigemptyset( &mask ); 360 sigaddset( &mask, SIGALRM ); 361 360 362 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 361 363 abort( "internal error, pthread_sigmask" ); 362 364 } 363 364 sigemptyset( &mask );365 sigaddset( &mask, SIGALRM );366 365 367 366 // Main loop -
src/libcfa/concurrency/thread.c
r2b22e050 r1dbc8590 39 39 curr_cluster = &cl; 40 40 next = NULL; 41 42 node.next = NULL; 43 node.prev = NULL; 44 doregister(this); 41 __cfaabi_dbg_debug_do( 42 dbg_next = NULL; 43 dbg_prev = NULL; 44 __cfaabi_dbg_thread_register(&this); 45 ) 45 46 46 47 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 48 49 49 50 void ^?{}(thread_desc& this) with( this ) { 50 unregister(this);51 51 ^self_cor{}; 52 52 } -
src/libcfa/interpose.c
r2b22e050 r1dbc8590 98 98 #pragma GCC diagnostic pop 99 99 100 // Failure handler 101 __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); 102 __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); 103 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO ); 104 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO ); 105 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND); 106 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO ); 107 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO ); 100 __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler 101 __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler 102 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO ); // Failure handler 103 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO ); // Failure handler 104 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO ); // Failure handler 105 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO ); // Failure handler 106 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO ); // Failure handler 108 107 } 109 108 }
Note:
See TracChangeset
for help on using the changeset viewer.