Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/preemption.c

    r65deb18 rb2b44d8  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:36:05 2017
    13 // Update Count     : 2
     12// Last Modified On : Tue Jan 23 17:59:30 2018
     13// Update Count     : 7
    1414//
    1515
    1616#include "preemption.h"
    1717
     18#define ftype `ftype`
    1819extern "C" {
    1920#include <errno.h>
    20 #include <execinfo.h>
    21 #define __USE_GNU
    22 #include <signal.h>
    23 #undef __USE_GNU
    2421#include <stdio.h>
    2522#include <string.h>
    2623#include <unistd.h>
    2724}
    28 
    29 
    30 #ifdef __USE_STREAM__
    31 #include "fstream"
    32 #endif
     25#undef ftype
     26
     27#include "bits/signal.h"
    3328
    3429//TODO move to defaults
     
    3934        return __CFA_DEFAULT_PREEMPTION__;
    4035}
    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
    4536
    4637// FwdDeclarations : timeout handlers
     
    5344void sigHandler_abort    ( __CFA_SIGPARMS__ );
    5445
    55 // FwdDeclarations : sigaction wrapper
    56 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
    57 
    5846// FwdDeclarations : alarm thread main
    5947void * alarm_loop( __attribute__((unused)) void * args );
    6048
    6149// Machine specific register name
    62 #ifdef __x86_64__
    63 #define CFA_REG_IP REG_RIP
    64 #else
    65 #define CFA_REG_IP REG_EIP
     50#if   defined(__x86_64__)
     51#define CFA_REG_IP gregs[REG_RIP]
     52#elif defined(__i386__)
     53#define CFA_REG_IP gregs[REG_EIP]
     54#elif defined(__ARM_ARCH__)
     55#define CFA_REG_IP arm_pc
    6656#endif
    6757
     
    179169        void enable_interrupts_noPoll() {
    180170                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    181                 verify( prev != 0u );                     // If this triggers someone is enabled already enabled interrupts
     171                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    182172        }
    183173}
     
    243233        // Setup proper signal handlers
    244234        __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
    247235
    248236        signal_block( SIGALRM );
     
    296284// Receives SIGUSR1 signal and causes the current thread to yield
    297285void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    298         __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
     286        __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.CFA_REG_IP); )
    299287
    300288        // Check if it is safe to preempt here
    301289        if( !preemption_ready() ) { return; }
     290
     291        __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    302292
    303293        preemption_in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
     
    371361}
    372362
    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 
    502363// Local Variables: //
    503364// mode: c //
Note: See TracChangeset for help on using the changeset viewer.