Changes in / [cfff639:89eff25]


Ignore:
Location:
libcfa/src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/locks.hfa

    rcfff639 r89eff25  
    3737        extern "C" {
    3838                extern void disable_interrupts() OPTIONAL_THREAD;
    39                 extern void enable_interrupts( bool poll = true ) OPTIONAL_THREAD;
     39                extern void enable_interrupts_noPoll() OPTIONAL_THREAD;
    4040
    4141                #ifdef __CFA_DEBUG__
     
    5757                        __cfaabi_dbg_record_lock( this, caller );
    5858                } else {
    59                         enable_interrupts( false );
     59                        enable_interrupts_noPoll();
    6060                }
    6161                return result;
     
    9090        static inline void unlock( __spinlock_t & this ) {
    9191                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    92                 enable_interrupts( false );
     92                enable_interrupts_noPoll();
    9393        }
    9494#endif
  • libcfa/src/concurrency/alarm.cfa

    rcfff639 r89eff25  
    116116        unlock( event_kernel->lock );
    117117        this->set = true;
    118         enable_interrupts();
     118        enable_interrupts( __cfaabi_dbg_ctx );
    119119}
    120120
     
    127127        }
    128128        unlock( event_kernel->lock );
    129         enable_interrupts();
     129        enable_interrupts( __cfaabi_dbg_ctx );
    130130        this->set = false;
    131131}
  • libcfa/src/concurrency/clib/cfathread.cfa

    rcfff639 r89eff25  
    117117
    118118        this_thrd->state = Ready;
    119         enable_interrupts();
     119        enable_interrupts( __cfaabi_dbg_ctx );
    120120}
    121121
  • libcfa/src/concurrency/invoke.c

    rcfff639 r89eff25  
    3434
    3535extern void disable_interrupts() OPTIONAL_THREAD;
    36 extern void enable_interrupts( _Bool poll );
     36extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    3737
    3838void __cfactx_invoke_coroutine(
     
    8282) {
    8383        // Officially start the thread by enabling preemption
    84         enable_interrupts( true );
     84        enable_interrupts( __cfaabi_dbg_ctx );
    8585
    8686        // Call the main of the thread
  • libcfa/src/concurrency/io.cfa

    rcfff639 r89eff25  
    244244                        // Allocation was successful
    245245                        __STATS__( true, io.alloc.fast += 1; )
    246                         enable_interrupts();
     246                        enable_interrupts( __cfaabi_dbg_ctx );
    247247
    248248                        __cfadbg_print_safe(io, "Kernel I/O : fast allocation successful from ring %d\n", ctx->fd);
     
    256256                // Fast path failed, fallback on arbitration
    257257                __STATS__( true, io.alloc.slow += 1; )
    258                 enable_interrupts();
     258                enable_interrupts( __cfaabi_dbg_ctx );
    259259
    260260                $io_arbiter * ioarb = proc->cltr->io.arbiter;
     
    314314                        // Mark the instance as no longer in-use, re-enable interrupts and return
    315315                        __STATS__( true, io.submit.fast += 1; )
    316                         enable_interrupts();
     316                        enable_interrupts( __cfaabi_dbg_ctx );
    317317
    318318                        __cfadbg_print_safe(io, "Kernel I/O : submitted on fast path\n");
     
    322322                // Fast path failed, fallback on arbitration
    323323                __STATS__( true, io.submit.slow += 1; )
    324                 enable_interrupts();
     324                enable_interrupts( __cfaabi_dbg_ctx );
    325325
    326326                __cfadbg_print_safe(io, "Kernel I/O : falling back on arbiter for submission\n");
  • libcfa/src/concurrency/kernel.cfa

    rcfff639 r89eff25  
    115115static $thread * __next_thread(cluster * this);
    116116static $thread * __next_thread_slow(cluster * this);
    117 static inline bool __must_unpark( $thread * thrd ) __attribute((nonnull(1)));
    118117static void __run_thread(processor * this, $thread * dst);
    119118static void __wake_one(cluster * cltr);
     
    131130extern void __disable_interrupts_hard();
    132131extern void __enable_interrupts_hard();
    133 
    134 static inline void __disable_interrupts_checked() {
    135         /* paranoid */ verify( __preemption_enabled() );
    136         disable_interrupts();
    137         /* paranoid */ verify( ! __preemption_enabled() );
    138 }
    139 
    140 static inline void __enable_interrupts_checked( bool poll = true ) {
    141         /* paranoid */ verify( ! __preemption_enabled() );
    142         enable_interrupts( poll );
    143         /* paranoid */ verify( __preemption_enabled() );
    144 }
    145132
    146133//=============================================================================================
     
    465452                if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    466453                        // The thread was preempted, reschedule it and reset the flag
    467                         schedule_thread$( thrd_dst );
     454                        __schedule_thread( thrd_dst );
    468455                        break RUNNING;
    469456                }
     
    554541        /* paranoid */ verify( ! __preemption_enabled() );
    555542        /* paranoid */ verify( kernelTLS().this_proc_id );
    556         /* paranoid */ verify( ready_schedule_islocked());
    557543        /* paranoid */ verify( thrd );
    558544        /* paranoid */ verify( thrd->state != Halted );
     
    574560        __STATS(bool outside = thrd->last_proc && thrd->last_proc != kernelTLS().this_processor; )
    575561
    576         // push the thread to the cluster ready-queue
    577         push( cl, thrd );
    578 
    579         // variable thrd is no longer safe to use
    580         thrd = 0xdeaddeaddeaddeadp;
    581 
    582         // wake the cluster using the save variable.
    583         __wake_one( cl );
     562        ready_schedule_lock();
     563                // push the thread to the cluster ready-queue
     564                push( cl, thrd );
     565
     566                // variable thrd is no longer safe to use
     567
     568                // wake the cluster using the save variable.
     569                __wake_one( cl );
     570        ready_schedule_unlock();
    584571
    585572        #if !defined(__CFA_NO_STATISTICS__)
     
    598585        #endif
    599586
    600         /* paranoid */ verify( ready_schedule_islocked());
    601         /* paranoid */ verify( ! __preemption_enabled() );
    602 }
    603 
    604 void schedule_thread$( $thread * thrd ) {
    605         ready_schedule_lock();
    606                 __schedule_thread( thrd );
    607         ready_schedule_unlock();
     587        /* paranoid */ verify( ! __preemption_enabled() );
    608588}
    609589
     
    643623}
    644624
    645 static inline bool __must_unpark( $thread * thrd ) {
     625void unpark( $thread * thrd ) {
     626        if( !thrd ) return;
     627
    646628        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    647629        switch(old_ticket) {
    648630                case TICKET_RUNNING:
    649631                        // Wake won the race, the thread will reschedule/rerun itself
    650                         return false;
     632                        break;
    651633                case TICKET_BLOCKED:
    652634                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    653635                        /* paranoid */ verify( thrd->state == Blocked );
    654                         return true;
     636
     637                        {
     638                                /* paranoid */ verify( publicTLS_get(this_proc_id) );
     639                                disable_interrupts();
     640
     641                                /* paranoid */ verify( ! __preemption_enabled() );
     642
     643                                // Wake lost the race,
     644                                __schedule_thread( thrd );
     645
     646                                /* paranoid */ verify( ! __preemption_enabled() );
     647
     648                                enable_interrupts_noPoll();
     649                                /* paranoid */ verify( publicTLS_get(this_proc_id) );
     650                        }
     651
     652                        break;
    655653                default:
    656654                        // This makes no sense, something is wrong abort
     
    659657}
    660658
    661 void unpark( $thread * thrd ) {
    662         if( !thrd ) return;
    663 
    664         if(__must_unpark(thrd)) {
    665                 disable_interrupts();
    666                         // Wake lost the race,
    667                         schedule_thread$( thrd );
    668                 enable_interrupts(false);
    669         }
    670 }
    671 
    672659void park( void ) {
    673         __disable_interrupts_checked();
    674                 /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
    675                 returnToKernel();
    676         __enable_interrupts_checked();
     660        /* paranoid */ verify( __preemption_enabled() );
     661        disable_interrupts();
     662        /* paranoid */ verify( ! __preemption_enabled() );
     663        /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
     664
     665        returnToKernel();
     666
     667        /* paranoid */ verify( ! __preemption_enabled() );
     668        enable_interrupts( __cfaabi_dbg_ctx );
     669        /* paranoid */ verify( __preemption_enabled() );
    677670
    678671}
     
    714707// KERNEL ONLY
    715708bool force_yield( __Preemption_Reason reason ) {
    716         __disable_interrupts_checked();
    717                 $thread * thrd = kernelTLS().this_thread;
    718                 /* paranoid */ verify(thrd->state == Active);
    719 
    720                 // SKULLDUGGERY: It is possible that we are preempting this thread just before
    721                 // it was going to park itself. If that is the case and it is already using the
    722                 // intrusive fields then we can't use them to preempt the thread
    723                 // If that is the case, abandon the preemption.
    724                 bool preempted = false;
    725                 if(thrd->link.next == 0p) {
    726                         preempted = true;
    727                         thrd->preempted = reason;
    728                         returnToKernel();
    729                 }
    730         __enable_interrupts_checked( false );
     709        /* paranoid */ verify( __preemption_enabled() );
     710        disable_interrupts();
     711        /* paranoid */ verify( ! __preemption_enabled() );
     712
     713        $thread * thrd = kernelTLS().this_thread;
     714        /* paranoid */ verify(thrd->state == Active);
     715
     716        // SKULLDUGGERY: It is possible that we are preempting this thread just before
     717        // it was going to park itself. If that is the case and it is already using the
     718        // intrusive fields then we can't use them to preempt the thread
     719        // If that is the case, abandon the preemption.
     720        bool preempted = false;
     721        if(thrd->link.next == 0p) {
     722                preempted = true;
     723                thrd->preempted = reason;
     724                returnToKernel();
     725        }
     726
     727        /* paranoid */ verify( ! __preemption_enabled() );
     728        enable_interrupts_noPoll();
     729        /* paranoid */ verify( __preemption_enabled() );
     730
    731731        return preempted;
    732732}
     
    773773        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    774774
    775         __disable_interrupts_checked();
     775        disable_interrupts();
    776776                /* paranoid */ verify( ! __preemption_enabled() );
    777777                eventfd_t val;
    778778                val = 1;
    779779                eventfd_write( this->idle, val );
    780         __enable_interrupts_checked();
     780        enable_interrupts( __cfaabi_dbg_ctx );
    781781}
    782782
  • libcfa/src/concurrency/kernel/fwd.hfa

    rcfff639 r89eff25  
    108108
    109109        extern void disable_interrupts();
    110         extern void enable_interrupts( bool poll = false );
     110        extern void enable_interrupts_noPoll();
     111        extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    111112
    112113        extern "Cforall" {
     
    402403                                        __VA_ARGS__ \
    403404                                } \
    404                                 if( !(in_kernel) ) enable_interrupts(); \
     405                                if( !(in_kernel) ) enable_interrupts( __cfaabi_dbg_ctx ); \
    405406                        }
    406407                #else
  • libcfa/src/concurrency/kernel/startup.cfa

    rcfff639 r89eff25  
    225225        // Add the main thread to the ready queue
    226226        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
    227         schedule_thread$(mainThread);
     227        __schedule_thread(mainThread);
    228228
    229229        // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX
     
    238238
    239239        /* paranoid */ verify( ! __preemption_enabled() );
    240         enable_interrupts();
     240        enable_interrupts( __cfaabi_dbg_ctx );
    241241        /* paranoid */ verify( __preemption_enabled() );
    242242
     
    532532        disable_interrupts();
    533533                init( this, name, _cltr, initT );
    534         enable_interrupts();
     534        enable_interrupts( __cfaabi_dbg_ctx );
    535535
    536536        __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
     
    559559        disable_interrupts();
    560560                deinit( this );
    561         enable_interrupts();
     561        enable_interrupts( __cfaabi_dbg_ctx );
    562562}
    563563
     
    597597        // Unlock the RWlock
    598598        ready_mutate_unlock( last_size );
    599         enable_interrupts( false ); // Don't poll, could be in main cluster
     599        enable_interrupts_noPoll(); // Don't poll, could be in main cluster
    600600}
    601601
     
    612612        // Unlock the RWlock
    613613        ready_mutate_unlock( last_size );
    614         enable_interrupts( false ); // Don't poll, could be in main cluster
     614        enable_interrupts_noPoll(); // Don't poll, could be in main cluster
    615615
    616616        #if !defined(__CFA_NO_STATISTICS__)
  • libcfa/src/concurrency/kernel_private.hfa

    rcfff639 r89eff25  
    2929extern "C" {
    3030        void disable_interrupts() OPTIONAL_THREAD;
    31         void enable_interrupts( bool poll = true );
    32 }
    33 
    34 void schedule_thread$( $thread * ) __attribute__((nonnull (1)));
     31        void enable_interrupts_noPoll();
     32        void enable_interrupts( __cfaabi_dbg_ctx_param );
     33}
     34
     35void __schedule_thread( $thread * )
     36#if defined(NDEBUG) || (!defined(__CFA_DEBUG__) && !defined(__CFA_VERIFY__))
     37        __attribute__((nonnull (1)))
     38#endif
     39;
    3540
    3641extern bool __preemption_enabled();
  • libcfa/src/concurrency/preemption.cfa

    rcfff639 r89eff25  
    315315        // Enable interrupts by decrementing the counter
    316316        // If counter reaches 0, execute any pending __cfactx_switch
    317         void enable_interrupts( bool poll ) {
     317        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    318318                // Cache the processor now since interrupts can start happening after the atomic store
    319319                processor   * proc = __cfaabi_tls.this_processor;
    320                 /* paranoid */ verify( !poll || proc );
     320                /* paranoid */ verify( proc );
    321321
    322322                with( __cfaabi_tls.preemption_state ){
     
    340340                                // Signal the compiler that a fence is needed but only for signal handlers
    341341                                __atomic_signal_fence(__ATOMIC_RELEASE);
    342                                 if( poll && proc->pending_preemption ) {
     342                                if( proc->pending_preemption ) {
    343343                                        proc->pending_preemption = false;
    344344                                        force_yield( __POLL_PREEMPTION );
    345345                                }
    346346                        }
     347                }
     348
     349                // For debugging purposes : keep track of the last person to enable the interrupts
     350                __cfaabi_dbg_debug_do( proc->last_enable = caller; )
     351        }
     352
     353        // Disable interrupts by incrementint the counter
     354        // Don't execute any pending __cfactx_switch even if counter reaches 0
     355        void enable_interrupts_noPoll() {
     356                unsigned short prev = __cfaabi_tls.preemption_state.disable_count;
     357                __cfaabi_tls.preemption_state.disable_count -= 1;
     358                // If this triggers someone is enabled already enabled interrupts
     359                /* paranoid */ verifyf( prev != 0u, "Incremented from %u\n", prev );
     360                if( prev == 1 ) {
     361                        #if GCC_VERSION > 50000
     362                                static_assert(__atomic_always_lock_free(sizeof(__cfaabi_tls.preemption_state.enabled), &__cfaabi_tls.preemption_state.enabled), "Must be lock-free");
     363                        #endif
     364                        // Set enabled flag to true
     365                        // should be atomic to avoid preemption in the middle of the operation.
     366                        // use memory order RELAXED since there is no inter-thread on this variable requirements
     367                        __atomic_store_n(&__cfaabi_tls.preemption_state.enabled, true, __ATOMIC_RELAXED);
     368
     369                        // Signal the compiler that a fence is needed but only for signal handlers
     370                        __atomic_signal_fence(__ATOMIC_RELEASE);
    347371                }
    348372        }
  • libcfa/src/concurrency/thread.cfa

    rcfff639 r89eff25  
    136136        /* paranoid */ verify( this_thrd->context.SP );
    137137
    138         schedule_thread$( this_thrd );
    139         enable_interrupts();
     138        __schedule_thread( this_thrd );
     139        enable_interrupts( __cfaabi_dbg_ctx );
    140140}
    141141
     
    170170        disable_interrupts();
    171171        uint64_t ret = __tls_rand();
    172         enable_interrupts();
     172        enable_interrupts( __cfaabi_dbg_ctx );
    173173        return ret;
    174174}
  • libcfa/src/startup.cfa

    rcfff639 r89eff25  
    3939
    4040    void disable_interrupts() __attribute__(( weak )) {}
    41     void enable_interrupts() __attribute__(( weak )) {}
     41    void enable_interrupts_noPoll() __attribute__(( weak )) {}
    4242} // extern "C"
    4343
Note: See TracChangeset for help on using the changeset viewer.