Ignore:
File:
1 edited

Legend:

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

    r2e9aed4 r65deb18  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jan 23 17:59:30 2018
    13 // Update Count     : 7
     12// Last Modified On : Fri Jul 21 22:36:05 2017
     13// Update Count     : 2
    1414//
    1515
    1616#include "preemption.h"
    1717
    18 #define ftype `ftype`
    1918extern "C" {
    2019#include <errno.h>
     20#include <execinfo.h>
     21#define __USE_GNU
     22#include <signal.h>
     23#undef __USE_GNU
    2124#include <stdio.h>
    2225#include <string.h>
    2326#include <unistd.h>
    2427}
    25 #undef ftype
    26 
    27 #include "bits/signal.h"
     28
     29
     30#ifdef __USE_STREAM__
     31#include "fstream"
     32#endif
    2833
    2934//TODO move to defaults
     
    3439        return __CFA_DEFAULT_PREEMPTION__;
    3540}
     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
    3645
    3746// FwdDeclarations : timeout handlers
     
    4453void sigHandler_abort    ( __CFA_SIGPARMS__ );
    4554
     55// FwdDeclarations : sigaction wrapper
     56static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags );
     57
    4658// FwdDeclarations : alarm thread main
    4759void * alarm_loop( __attribute__((unused)) void * args );
    4860
    4961// Machine specific register name
    50 #if   defined(__x86_64__)
     62#ifdef __x86_64__
    5163#define CFA_REG_IP REG_RIP
    52 #elif defined(__i386__)
     64#else
    5365#define CFA_REG_IP REG_EIP
    54 #elif defined(__ARM_ARCH__)
    55 #define CFA_REG_IP REG_R15
    5666#endif
    5767
     
    6070static pthread_t alarm_thread;                        // pthread handle to alarm thread
    6171
    62 void ?{}(event_kernel_t & this) {
    63         (this.alarms){};
    64         (this.lock){};
     72void ?{}(event_kernel_t & this) with( this ) {
     73        alarms{};
     74        lock{};
    6575}
    6676
     
    149159        // If counter reaches 0, execute any pending CtxSwitch
    150160        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    151                 processor * proc  = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
     161                processor   * proc = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
    152162                thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
    153163
     
    169179        void enable_interrupts_noPoll() {
    170180                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    171                 verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
     181                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interrupts
    172182        }
    173183}
     
    233243        // Setup proper signal handlers
    234244        __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
    235247
    236248        signal_block( SIGALRM );
     
    284296// Receives SIGUSR1 signal and causes the current thread to yield
    285297void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    286 #if defined( __ARM_ARCH )
    287         __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.arm_pc); )
    288 #else
    289298        __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
    293301        if( !preemption_ready() ) { return; }
    294 
    295         __cfaabi_dbg_print_buffer_decl(" KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    296302
    297303        preemption_in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
     
    365371}
    366372
     373// Sigaction wrapper : register an signal handler
     374static 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
     390static 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
    367502// Local Variables: //
    368503// mode: c //
Note: See TracChangeset for help on using the changeset viewer.