- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/preemption.c
r2e9aed4 r65deb18 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jan 23 17:59:30 201813 // Update Count : 712 // Last Modified On : Fri Jul 21 22:36:05 2017 13 // Update Count : 2 14 14 // 15 15 16 16 #include "preemption.h" 17 17 18 #define ftype `ftype`19 18 extern "C" { 20 19 #include <errno.h> 20 #include <execinfo.h> 21 #define __USE_GNU 22 #include <signal.h> 23 #undef __USE_GNU 21 24 #include <stdio.h> 22 25 #include <string.h> 23 26 #include <unistd.h> 24 27 } 25 #undef ftype 26 27 #include "bits/signal.h" 28 29 30 #ifdef __USE_STREAM__ 31 #include "fstream" 32 #endif 28 33 29 34 //TODO move to defaults … … 34 39 return __CFA_DEFAULT_PREEMPTION__; 35 40 } 41 42 // Short hands for signal context information 43 #define __CFA_SIGCXT__ ucontext_t * 44 #define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt 36 45 37 46 // FwdDeclarations : timeout handlers … … 44 53 void sigHandler_abort ( __CFA_SIGPARMS__ ); 45 54 55 // FwdDeclarations : sigaction wrapper 56 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ); 57 46 58 // FwdDeclarations : alarm thread main 47 59 void * alarm_loop( __attribute__((unused)) void * args ); 48 60 49 61 // Machine specific register name 50 #if defined(__x86_64__)62 #ifdef __x86_64__ 51 63 #define CFA_REG_IP REG_RIP 52 #el if defined(__i386__)64 #else 53 65 #define CFA_REG_IP REG_EIP 54 #elif defined(__ARM_ARCH__)55 #define CFA_REG_IP REG_R1556 66 #endif 57 67 … … 60 70 static pthread_t alarm_thread; // pthread handle to alarm thread 61 71 62 void ?{}(event_kernel_t & this) {63 (this.alarms){};64 (this.lock){};72 void ?{}(event_kernel_t & this) with( this ) { 73 alarms{}; 74 lock{}; 65 75 } 66 76 … … 149 159 // If counter reaches 0, execute any pending CtxSwitch 150 160 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 151 processor * proc= this_processor; // Cache the processor now since interrupts can start happening after the atomic add161 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 152 162 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add 153 163 … … 169 179 void enable_interrupts_noPoll() { 170 180 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 171 verify f( prev != 0u, "Incremented from %u\n", prev); // If this triggers someone is enabled already enabled interrupts181 verify( prev != 0u ); // If this triggers someone is enabled already enabled interrupts 172 182 } 173 183 } … … 233 243 // Setup proper signal handlers 234 244 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // CtxSwitch handler 245 // __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler 246 // __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler 235 247 236 248 signal_block( SIGALRM ); … … 284 296 // Receives SIGUSR1 signal and causes the current thread to yield 285 297 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 286 #if defined( __ARM_ARCH )287 __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.arm_pc); )288 #else289 298 __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 290 #endif 291 292 // Check if it is safe to preempt here 299 300 // Check if it is safe to preempt here 293 301 if( !preemption_ready() ) { return; } 294 295 __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);296 302 297 303 preemption_in_progress = true; // Sync flag : prevent recursive calls to the signal handler … … 365 371 } 366 372 373 // Sigaction wrapper : register an signal handler 374 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) { 375 struct sigaction act; 376 377 act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler; 378 act.sa_flags = flags; 379 380 if ( sigaction( sig, &act, NULL ) == -1 ) { 381 __cfaabi_dbg_print_buffer_decl( 382 " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n", 383 sig, handler, flags, errno, strerror( errno ) 384 ); 385 _exit( EXIT_FAILURE ); 386 } 387 } 388 389 // Sigaction wrapper : restore default handler 390 static void __kernel_sigdefault( int sig ) { 391 struct sigaction act; 392 393 act.sa_handler = SIG_DFL; 394 act.sa_flags = 0; 395 sigemptyset( &act.sa_mask ); 396 397 if ( sigaction( sig, &act, NULL ) == -1 ) { 398 __cfaabi_dbg_print_buffer_decl( 399 " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n", 400 sig, errno, strerror( errno ) 401 ); 402 _exit( EXIT_FAILURE ); 403 } 404 } 405 406 //============================================================================================= 407 // Terminating Signals logic 408 //============================================================================================= 409 410 __cfaabi_dbg_debug_do( 411 static void __kernel_backtrace( int start ) { 412 // skip first N stack frames 413 414 enum { Frames = 50 }; 415 void * array[Frames]; 416 int size = backtrace( array, Frames ); 417 char ** messages = backtrace_symbols( array, size ); 418 419 // find executable name 420 *index( messages[0], '(' ) = '\0'; 421 #ifdef __USE_STREAM__ 422 serr | "Stack back trace for:" | messages[0] | endl; 423 #else 424 fprintf( stderr, "Stack back trace for: %s\n", messages[0]); 425 #endif 426 427 // skip last 2 stack frames after main 428 for ( int i = start; i < size && messages != NULL; i += 1 ) { 429 char * name = NULL; 430 char * offset_begin = NULL; 431 char * offset_end = NULL; 432 433 for ( char *p = messages[i]; *p; ++p ) { 434 // find parantheses and +offset 435 if ( *p == '(' ) { 436 name = p; 437 } 438 else if ( *p == '+' ) { 439 offset_begin = p; 440 } 441 else if ( *p == ')' ) { 442 offset_end = p; 443 break; 444 } 445 } 446 447 // if line contains symbol print it 448 int frameNo = i - start; 449 if ( name && offset_begin && offset_end && name < offset_begin ) { 450 // delimit strings 451 *name++ = '\0'; 452 *offset_begin++ = '\0'; 453 *offset_end++ = '\0'; 454 455 #ifdef __USE_STREAM__ 456 serr | "(" | frameNo | ")" | messages[i] | ":" 457 | name | "+" | offset_begin | offset_end | endl; 458 #else 459 fprintf( stderr, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end); 460 #endif 461 } 462 // otherwise, print the whole line 463 else { 464 #ifdef __USE_STREAM__ 465 serr | "(" | frameNo | ")" | messages[i] | endl; 466 #else 467 fprintf( stderr, "(%i) %s\n", frameNo, messages[i] ); 468 #endif 469 } 470 } 471 472 free( messages ); 473 } 474 ) 475 476 // void sigHandler_segv( __CFA_SIGPARMS__ ) { 477 // __cfaabi_dbg_debug_do( 478 // #ifdef __USE_STREAM__ 479 // serr | "*CFA runtime error* program cfa-cpp terminated with" 480 // | (sig == SIGSEGV ? "segment fault." : "bus error.") 481 // | endl; 482 // #else 483 // fprintf( stderr, "*CFA runtime error* program cfa-cpp terminated with %s\n", sig == SIGSEGV ? "segment fault." : "bus error." ); 484 // #endif 485 486 // // skip first 2 stack frames 487 // __kernel_backtrace( 1 ); 488 // ) 489 // exit( EXIT_FAILURE ); 490 // } 491 492 // void sigHandler_abort( __CFA_SIGPARMS__ ) { 493 // // skip first 6 stack frames 494 // __cfaabi_dbg_debug_do( __kernel_backtrace( 6 ); ) 495 496 // // reset default signal handler 497 // __kernel_sigdefault( SIGABRT ); 498 499 // raise( SIGABRT ); 500 // } 501 367 502 // Local Variables: // 368 503 // mode: c //
Note: See TracChangeset
for help on using the changeset viewer.