Changes in / [dafbde8:fd54fef]
- Location:
- libcfa/src
- Files:
-
- 3 edited
-
concurrency/kernel.cfa (modified) (2 diffs)
-
concurrency/preemption.cfa (modified) (1 diff)
-
interpose.cfa (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
rdafbde8 rfd54fef 624 624 // Unexpected Terminating logic 625 625 //============================================================================================= 626 void __kernel_abort_msg( char * abort_text, int abort_text_size ) { 627 $thread * thrd = __cfaabi_tls.this_thread; 626 627 extern "C" { 628 extern void __cfaabi_real_abort(void); 629 } 630 static volatile bool kernel_abort_called = false; 631 632 void * kernel_abort(void) __attribute__ ((__nothrow__)) { 633 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 634 // the globalAbort flag is true. 635 bool first = !__atomic_test_and_set( &kernel_abort_called, __ATOMIC_SEQ_CST); 636 637 // first task to abort ? 638 if ( !first ) { 639 // We aren't the first to abort. 640 // I give up, just let C handle it 641 __cfaabi_real_abort(); 642 } 643 644 // disable interrupts, it no longer makes sense to try to interrupt this processor 645 disable_interrupts(); 646 647 return __cfaabi_tls.this_thread; 648 } 649 650 void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) { 651 $thread * thrd = ( $thread * ) kernel_data; 628 652 629 653 if(thrd) { … … 645 669 } 646 670 647 int __kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {648 return get_coroutine( __cfaabi_tls.this_thread) == get_coroutine(mainThread) ? 4 : 2;671 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 672 return get_coroutine(kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2; 649 673 } 650 674 -
libcfa/src/concurrency/preemption.cfa
rdafbde8 rfd54fef 616 616 } 617 617 618 // Prevent preemption since we are about to start terminating things619 void __kernel_abort_lock(void) {620 signal_block( SIGUSR1 );621 }622 623 618 // Raii ctor/dtor for the preemption_scope 624 619 // Used by thread to control when they want to receive preemption signals -
libcfa/src/interpose.cfa
rdafbde8 rfd54fef 125 125 126 126 // Failure handler 127 // internal errors 128 __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); // Invalid memory reference (default: Core) 129 __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); // Bus error, bad memory access (default: Core) 130 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK ); // Illegal Instruction (default: Core) 131 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK ); // Floating-point exception (default: Core) 132 133 // handlers to outside errors 134 // reset in-case they insist and send it over and over 135 __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Termination signal (default: Term) 136 __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Interrupt from keyboard (default: Term) 137 __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Hangup detected on controlling terminal or death of controlling process (default: Term) 138 __cfaabi_sigaction( SIGQUIT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Quit from keyboard (default: Core) 139 __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Abort signal from abort(3) (default: Core) 127 __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); 128 __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); 129 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK ); 130 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK ); 131 __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // one shot handler, return to default 132 __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); 133 __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); 134 __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // terminal hangup 140 135 } 141 136 } … … 168 163 } 169 164 170 // See concurrency/kernel.cfa and concurrency/preemption.cfa for strong definition used in multi-processor mode. 171 void __kernel_abort_lock( void) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}172 void __kernel_abort_msg( char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {} 173 int __kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }165 void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; } 166 void kernel_abort_msg( void * data, char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {} 167 // See concurrency/kernel.cfa for strong definition used in multi-processor mode. 168 int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; } 174 169 175 170 enum { abort_text_size = 1024 }; … … 178 173 static void __cfaabi_backtrace( int start ) { 179 174 enum { Frames = 50, }; // maximum number of stack frames 180 int last = __kernel_abort_lastframe(); // skip last N stack frames175 int last = kernel_abort_lastframe(); // skip last N stack frames 181 176 182 177 void * array[Frames]; … … 225 220 } 226 221 227 static volatile bool __abort_first= 0;222 static volatile int __abort_stage = 0; 228 223 229 224 // Cannot forward va_list. 230 225 void __abort( bool signalAbort, const char fmt[], va_list args ) { 231 // Multiple threads can come here from multiple paths 232 // To make sure this is safe any concurrent/subsequent call to abort is redirected to libc-abort 233 bool first = ! __atomic_test_and_set( &__abort_first, __ATOMIC_SEQ_CST); 234 235 // Prevent preemption from kicking-in and messing with the abort 236 __kernel_abort_lock(); 237 238 // first to abort ? 239 if ( !first ) { 240 // We aren't the first to abort just let C handle it 241 signal( SIGABRT, SIG_DFL ); // restore default in case we came here through the function. 226 int stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST ); 227 228 // First stage: stop the cforall kernel and print 229 if(stage == 1) { 230 // increment stage 231 stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST ); 232 233 // must be done here to lock down kernel 234 void * kernel_data = kernel_abort(); 235 int len; 236 237 signal( SIGABRT, SIG_DFL ); // prevent final "real" abort from recursing to handler 238 239 len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid) 240 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 241 242 assert( fmt ); 243 len = vsnprintf( abort_text, abort_text_size, fmt, args ); 244 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 245 246 // add optional newline if missing at the end of the format text 247 if ( fmt[strlen( fmt ) - 1] != '\n' ) { 248 __cfaabi_bits_write( STDERR_FILENO, "\n", 1 ); 249 } // if 250 kernel_abort_msg( kernel_data, abort_text, abort_text_size ); 251 } 252 253 // Second stage: print the backtrace 254 if(stage == 2) { 255 // increment stage 256 stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST ); 257 258 // print stack trace in handler 259 __cfaabi_backtrace( signalAbort ? 4 : 2 ); 260 } 261 262 do { 263 // Finally call abort 242 264 __cabi_libc.abort(); 243 } 244 245 int len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid) 246 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 247 248 // print the cause of the error 249 assert( fmt ); 250 len = vsnprintf( abort_text, abort_text_size, fmt, args ); 251 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 252 253 // add optional newline if missing at the end of the format text 254 if ( fmt[strlen( fmt ) - 1] != '\n' ) { 255 __cfaabi_bits_write( STDERR_FILENO, "\n", 1 ); 256 } // if 257 258 // Give the kernel the chance to add some data in here 259 __kernel_abort_msg( abort_text, abort_text_size ); 260 261 // print stack trace in handler 262 __cfaabi_backtrace( signalAbort ? 4 : 2 ); 263 264 // Finally call abort 265 __cabi_libc.abort(); 266 265 266 // Loop so that we never return 267 } while(true); 267 268 } 268 269 … … 281 282 // CONTROL NEVER REACHES HERE! 282 283 va_end( args ); 284 } 285 286 extern "C" { 287 void __cfaabi_real_abort(void) { 288 __cabi_libc.abort(); 289 } 283 290 } 284 291
Note:
See TracChangeset
for help on using the changeset viewer.