Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel.cfa

    r454f478 r6011658  
    140140                preemption_scope scope = { this };
    141141
    142                 #if !defined(__CFA_NO_STATISTICS__)
    143                         unsigned long long last_tally = rdtscl();
    144                 #endif
    145 
    146 
    147142                __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this);
    148143
     
    211206                        // Are we done?
    212207                        if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    213 
    214                         #if !defined(__CFA_NO_STATISTICS__)
    215                                 unsigned long long curr = rdtscl();
    216                                 if(curr > (last_tally + 500000000)) {
    217                                         __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);
    218                                         last_tally = curr;
    219                                 }
    220                         #endif
    221208                }
    222209
     
    224211        }
    225212
    226         post( this->terminated );
     213        V( this->terminated );
    227214
    228215        if(this == mainProcessor) {
     
    624611// Unexpected Terminating logic
    625612//=============================================================================================
    626 void __kernel_abort_msg( char * abort_text, int abort_text_size ) {
    627         $thread * thrd = __cfaabi_tls.this_thread;
     613static __spinlock_t kernel_abort_lock;
     614static bool kernel_abort_called = false;
     615
     616void * kernel_abort(void) __attribute__ ((__nothrow__)) {
     617        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
     618        // the globalAbort flag is true.
     619        lock( kernel_abort_lock __cfaabi_dbg_ctx2 );
     620
     621        // disable interrupts, it no longer makes sense to try to interrupt this processor
     622        disable_interrupts();
     623
     624        // first task to abort ?
     625        if ( kernel_abort_called ) {                    // not first task to abort ?
     626                unlock( kernel_abort_lock );
     627
     628                sigset_t mask;
     629                sigemptyset( &mask );
     630                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
     631                sigaddset( &mask, SIGUSR1 );            // block SIGALRM signals
     632                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
     633                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
     634        }
     635        else {
     636                kernel_abort_called = true;
     637                unlock( kernel_abort_lock );
     638        }
     639
     640        return __cfaabi_tls.this_thread;
     641}
     642
     643void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) {
     644        $thread * thrd = ( $thread * ) kernel_data;
    628645
    629646        if(thrd) {
     
    645662}
    646663
    647 int __kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    648         return get_coroutine(__cfaabi_tls.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     664int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
     665        return get_coroutine(kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2;
    649666}
    650667
     
    664681// Kernel Utilities
    665682//=============================================================================================
     683//-----------------------------------------------------------------------------
     684// Locks
     685void  ?{}( semaphore & this, int count = 1 ) {
     686        (this.lock){};
     687        this.count = count;
     688        (this.waiting){};
     689}
     690void ^?{}(semaphore & this) {}
     691
     692bool P(semaphore & this) with( this ){
     693        lock( lock __cfaabi_dbg_ctx2 );
     694        count -= 1;
     695        if ( count < 0 ) {
     696                // queue current task
     697                append( waiting, active_thread() );
     698
     699                // atomically release spin lock and block
     700                unlock( lock );
     701                park();
     702                return true;
     703        }
     704        else {
     705            unlock( lock );
     706            return false;
     707        }
     708}
     709
     710bool V(semaphore & this) with( this ) {
     711        $thread * thrd = 0p;
     712        lock( lock __cfaabi_dbg_ctx2 );
     713        count += 1;
     714        if ( count <= 0 ) {
     715                // remove task at head of waiting list
     716                thrd = pop_head( waiting );
     717        }
     718
     719        unlock( lock );
     720
     721        // make new owner
     722        unpark( thrd );
     723
     724        return thrd != 0p;
     725}
     726
     727bool V(semaphore & this, unsigned diff) with( this ) {
     728        $thread * thrd = 0p;
     729        lock( lock __cfaabi_dbg_ctx2 );
     730        int release = max(-count, (int)diff);
     731        count += diff;
     732        for(release) {
     733                unpark( pop_head( waiting ) );
     734        }
     735
     736        unlock( lock );
     737
     738        return thrd != 0p;
     739}
     740
    666741//-----------------------------------------------------------------------------
    667742// Debug
Note: See TracChangeset for help on using the changeset viewer.