Changeset de94a60
- Timestamp:
- May 11, 2018, 10:42:09 AM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
- Children:
- 78af962
- Parents:
- afd550c
- Location:
- src/libcfa
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/bits/containers.h
rafd550c rde94a60 191 191 //----------------------------------------------------------------------------- 192 192 #ifdef __cforall 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)) 193 forall(dtype TYPE | sized(TYPE)) 201 194 #define T TYPE 202 195 #else … … 205 198 struct __dllist { 206 199 T * head; 200 * [T * & next, T * & prev] ( T & ) __get; 207 201 }; 208 202 #undef T … … 216 210 #ifdef __cforall 217 211 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 // } 212 forall(dtype T | sized(T)) 213 static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) { 214 this.head{ NULL }; 215 this.__get = __get; 216 } 217 218 #define _next .0 219 #define _prev .1 220 forall(dtype T | sized(T)) 221 static inline void push_front( __dllist(T) & this, T & node ) with( this ) { 222 if ( head ) { 223 __get( node )_next = head; 224 __get( node )_prev = __get( *head )_prev; 225 // inserted node must be consistent before it is seen 226 // prevent code movement across barrier 227 asm( "" : : : "memory" ); 228 __get( *head )_prev = &node; 229 T & prev = *__get( node )_prev; 230 __get( prev )_next = &node; 231 } 232 else { 233 __get( node )_next = &node; 234 __get( node )_prev = &node; 235 } 236 237 // prevent code movement across barrier 238 asm( "" : : : "memory" ); 239 head = &node; 240 } 241 242 forall(dtype T | sized(T)) 243 static inline void remove( __dllist(T) & this, T & node ) with( this ) { 244 if ( &node == head ) { 245 if ( __get( *head )_next == head ) { 246 head = NULL; 247 } 248 else { 249 head = __get( *head )_next; 250 } 251 } 252 __get( *__get( node )_next )_prev = __get( node )_prev; 253 __get( *__get( node )_prev )_next = __get( node )_next; 254 __get( node )_next = NULL; 255 __get( node )_prev = NULL; 256 } 257 #undef _next 258 #undef _prev 260 259 #endif 261 260 -
src/libcfa/concurrency/invoke.h
rafd550c rde94a60 136 136 struct thread_desc * next; 137 137 138 __cfaabi_dbg_debug_do( 139 // instrusive link field for debugging 140 struct thread_desc * dbg_next; 141 struct thread_desc * dbg_prev; 142 ) 138 struct { 139 struct thread_desc * next; 140 struct thread_desc * prev; 141 } node; 143 142 }; 144 143 … … 147 146 static inline thread_desc * & get_next( thread_desc & this ) { 148 147 return this.next; 148 } 149 150 static inline [thread_desc *&, thread_desc *& ] __get( thread_desc & this ) { 151 return this.node.[next, prev]; 149 152 } 150 153 -
src/libcfa/concurrency/kernel
rafd550c rde94a60 40 40 41 41 //----------------------------------------------------------------------------- 42 // Cluster 43 struct cluster { 44 // Ready queue locks 45 __spinlock_t ready_queue_lock; 42 // Processor 43 extern struct cluster * mainCluster; 46 44 47 // Ready queue for threads48 __queue_t(thread_desc) ready_queue;49 50 // Name of the cluster51 const char * name;52 53 // Preemption rate on this cluster54 Duration preemption_rate;55 56 // List of idle processors57 // __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 //-----------------------------------------------------------------------------71 // Processor72 45 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule }; 73 46 … … 101 74 102 75 // Cluster from which to get threads 103 cluster * cltr;76 struct cluster * cltr; 104 77 105 78 // Name of the processor … … 127 100 bool pending_preemption; 128 101 102 // Idle lock 103 104 // Link lists fields 129 105 struct { 130 pthread_mutex_t lock;131 pthread_cond_t cond;132 } idle;106 struct processor * next; 107 struct processor * prev; 108 } node; 133 109 134 110 #ifdef __CFA_DEBUG__ … … 138 114 }; 139 115 140 void ?{}(processor & this, const char * name, cluster & cltr);116 void ?{}(processor & this, const char * name, struct cluster & cltr); 141 117 void ^?{}(processor & this); 142 118 143 119 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster}; } 144 static inline void ?{}(processor & this, cluster & cltr) { this{ "Anonymous Processor", cltr}; }120 static inline void ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr}; } 145 121 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 // Cluster 129 struct cluster { 130 // Ready queue locks 131 __spinlock_t ready_queue_lock; 132 133 // Ready queue for threads 134 __queue_t(thread_desc) ready_queue; 135 136 // Name of the cluster 137 const char * name; 138 139 // Preemption rate on this cluster 140 Duration preemption_rate; 141 142 // List of processors 143 __spinlock_t proc_list_lock; 144 __dllist_t(struct processor) procs; 145 __dllist_t(struct processor) idles; 146 147 // Link lists fields 148 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 } 146 165 147 166 // Local Variables: // -
src/libcfa/concurrency/kernel.c
rafd550c rde94a60 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 51 54 //----------------------------------------------------------------------------- 52 55 // Global state … … 117 120 self_mon_p = &self_mon; 118 121 next = NULL; 119 __cfaabi_dbg_debug_do( 120 dbg_next = NULL; 121 dbg_prev = NULL; 122 __cfaabi_dbg_thread_register(&this); 123 ) 122 123 node.next = NULL; 124 node.prev = NULL; 125 doregister(this); 124 126 125 127 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 167 169 ready_queue{}; 168 170 ready_queue_lock{}; 171 172 procs{ __get }; 173 idles{ __get }; 174 175 doregister(this); 169 176 } 170 177 171 178 void ^?{}(cluster & this) { 172 179 unregister(this); 173 180 } 174 181 … … 182 189 183 190 __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this); 191 192 doregister(this->cltr, this); 184 193 185 194 { … … 215 224 __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this); 216 225 } 226 227 unregister(this->cltr, this); 217 228 218 229 V( this->terminated ); … … 512 523 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 513 524 525 global_threads. list{ __get }; 526 global_threads. lock{}; 527 global_clusters.list{ __get }; 528 global_clusters.lock{}; 529 514 530 // Initialize the main cluster 515 531 mainCluster = (cluster *)&storage_mainCluster; … … 639 655 640 656 static __spinlock_t kernel_abort_lock; 641 static __spinlock_t kernel_debug_lock;642 657 static bool kernel_abort_called = false; 643 658 … … 648 663 649 664 // first task to abort ? 650 if ( ! kernel_abort_called ) { // not first task to abort ? 665 if ( kernel_abort_called ) { // not first task to abort ? 666 unlock( kernel_abort_lock ); 667 668 sigset_t mask; 669 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 { 651 675 kernel_abort_called = true; 652 676 unlock( kernel_abort_lock ); 653 677 } 654 else {655 unlock( kernel_abort_lock );656 657 sigset_t mask;658 sigemptyset( &mask );659 sigaddset( &mask, SIGALRM ); // block SIGALRM signals660 sigaddset( &mask, SIGUSR1 ); // block SIGUSR1 signals661 sigsuspend( &mask ); // block the processor to prevent further damage during abort662 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it663 }664 678 665 679 return kernelTLS.this_thread; … … 669 683 thread_desc * thrd = kernel_data; 670 684 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 ); 685 if(thrd) { 686 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd ); 676 687 __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 } 677 696 } 678 697 else { 679 __cfaabi_dbg_bits_write( ".\n", 2);698 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" ); 680 699 } 681 700 } … … 684 703 return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2; 685 704 } 705 706 static __spinlock_t kernel_debug_lock; 686 707 687 708 extern "C" { … … 738 759 739 760 //----------------------------------------------------------------------------- 761 // Global Queues 762 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 //----------------------------------------------------------------------------- 740 800 // Debug 741 801 __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 772 802 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) { 773 803 this.prev_name = prev_name; -
src/libcfa/concurrency/kernel_private.h
rafd550c rde94a60 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 102 112 // Local Variables: // 103 113 // mode: c // -
src/libcfa/concurrency/thread.c
rafd550c rde94a60 39 39 curr_cluster = &cl; 40 40 next = NULL; 41 __cfaabi_dbg_debug_do( 42 dbg_next = NULL; 43 dbg_prev = NULL; 44 __cfaabi_dbg_thread_register(&this); 45 ) 41 42 node.next = NULL; 43 node.prev = NULL; 44 doregister(this); 46 45 47 46 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 49 48 50 49 void ^?{}(thread_desc& this) with( this ) { 50 unregister(this); 51 51 ^self_cor{}; 52 52 } -
src/libcfa/interpose.c
rafd550c rde94a60 98 98 #pragma GCC diagnostic pop 99 99 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 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 ); 107 108 } 108 109 }
Note: See TracChangeset
for help on using the changeset viewer.