Changeset d0a045c


Ignore:
Timestamp:
Feb 1, 2018, 5:37:37 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
85521c7
Parents:
e76bd39
Message:

Faster (but maybe unsafe) interupt management

Location:
src/libcfa/concurrency
Files:
4 edited

Legend:

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

    re76bd39 rd0a045c  
    5959
    6060volatile thread_local bool preemption_in_progress = 0;
     61volatile thread_local bool preemption_enabled = false;
    6162volatile thread_local unsigned short disable_preempt_count = 1;
    6263
     
    196197                        if(readyThread)
    197198                        {
    198                                 verify( disable_preempt_count > 0 );
     199                                verify( !preemption_enabled );
    199200
    200201                                runThread(this, readyThread);
    201202
    202                                 verify( disable_preempt_count > 0 );
     203                                verify( !preemption_enabled );
    203204
    204205                                //Some actions need to be taken from the kernel
     
    242243void finishRunning(processor * this) with( this->finish ) {
    243244        if( action_code == Release ) {
    244                 verify( disable_preempt_count > 1 );
     245                verify( !preemption_enabled );
    245246                unlock( *lock );
    246247        }
     
    249250        }
    250251        else if( action_code == Release_Schedule ) {
    251                 verify( disable_preempt_count > 1 );
     252                verify( !preemption_enabled );
    252253                unlock( *lock );
    253254                ScheduleThread( thrd );
    254255        }
    255256        else if( action_code == Release_Multi ) {
    256                 verify( disable_preempt_count > lock_count );
     257                verify( !preemption_enabled );
    257258                for(int i = 0; i < lock_count; i++) {
    258259                        unlock( *locks[i] );
     
    286287        this_coroutine = NULL;
    287288        this_thread = NULL;
     289        preemption_enabled = false;
    288290        disable_preempt_count = 1;
    289291        // SKULLDUGGERY: We want to create a context for the processor coroutine
     
    333335        verify( thrd->self_cor.state != Halted );
    334336
    335         verify( disable_preempt_count > 0 );
     337        verify( !preemption_enabled );
    336338
    337339        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    343345        }
    344346
    345         verify( disable_preempt_count > 0 );
     347        verify( !preemption_enabled );
    346348}
    347349
    348350thread_desc * nextThread(cluster * this) with( *this ) {
    349         verify( disable_preempt_count > 0 );
     351        verify( !preemption_enabled );
    350352        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    351353        thread_desc * head = pop_head( ready_queue );
    352354        unlock( ready_queue_lock );
    353         verify( disable_preempt_count > 0 );
     355        verify( !preemption_enabled );
    354356        return head;
    355357}
     
    357359void BlockInternal() {
    358360        disable_interrupts();
    359         verify( disable_preempt_count > 0 );
    360         suspend();
    361         verify( disable_preempt_count > 0 );
     361        verify( !preemption_enabled );
     362        suspend();
     363        verify( !preemption_enabled );
    362364        enable_interrupts( __cfaabi_dbg_ctx );
    363365}
     
    368370        this_processor->finish.lock        = lock;
    369371
    370         verify( disable_preempt_count > 1 );
    371         suspend();
    372         verify( disable_preempt_count > 0 );
     372        verify( !preemption_enabled );
     373        suspend();
     374        verify( !preemption_enabled );
    373375
    374376        enable_interrupts( __cfaabi_dbg_ctx );
     
    380382        this_processor->finish.thrd        = thrd;
    381383
    382         verify( disable_preempt_count > 0 );
    383         suspend();
    384         verify( disable_preempt_count > 0 );
     384        verify( !preemption_enabled );
     385        suspend();
     386        verify( !preemption_enabled );
    385387
    386388        enable_interrupts( __cfaabi_dbg_ctx );
     
    394396        this_processor->finish.thrd        = thrd;
    395397
    396         verify( disable_preempt_count > 1 );
    397         suspend();
    398         verify( disable_preempt_count > 0 );
     398        verify( !preemption_enabled );
     399        suspend();
     400        verify( !preemption_enabled );
    399401
    400402        enable_interrupts( __cfaabi_dbg_ctx );
     
    407409        this_processor->finish.lock_count  = count;
    408410
    409         verify( disable_preempt_count > 0 );
    410         suspend();
    411         verify( disable_preempt_count > 0 );
     411        verify( !preemption_enabled );
     412        suspend();
     413        verify( !preemption_enabled );
    412414
    413415        enable_interrupts( __cfaabi_dbg_ctx );
     
    422424        this_processor->finish.thrd_count  = thrd_count;
    423425
    424         verify( disable_preempt_count > 0 );
    425         suspend();
    426         verify( disable_preempt_count > 0 );
     426        verify( !preemption_enabled );
     427        suspend();
     428        verify( !preemption_enabled );
    427429
    428430        enable_interrupts( __cfaabi_dbg_ctx );
     
    430432
    431433void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    432         verify( disable_preempt_count > 0 );
     434        verify( !preemption_enabled );
    433435        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
    434436        this_processor->finish.lock        = lock;
  • src/libcfa/concurrency/kernel_private.h

    re76bd39 rd0a045c  
    7474
    7575extern volatile thread_local bool preemption_in_progress;
     76extern volatile thread_local bool preemption_enabled;
    7677extern volatile thread_local unsigned short disable_preempt_count;
    7778
  • src/libcfa/concurrency/monitor.c

    re76bd39 rd0a045c  
    8787                thread_desc * thrd = this_thread;
    8888
    89                 verify( disable_preempt_count > 0 );
    90 
    9189                __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    9290
     
    117115                        // Some one else has the monitor, wait in line for it
    118116                        append( this->entry_queue, thrd );
    119 
    120                         verify( disable_preempt_count > 0 );
    121117
    122118                        BlockInternal( &this->lock );
     
    396392        append( this.blocked, &waiter );
    397393
    398         verify( disable_preempt_count == 0 );
    399 
    400394        // Lock all monitors (aggregates the locks as well)
    401395        lock_all( monitors, locks, count );
    402 
    403         // verifyf( disable_preempt_count == count, "Got %d, expected %d\n", disable_preempt_count, count );
    404         if(disable_preempt_count != count) { __cfaabi_dbg_print_buffer_decl("----------Gonna crash\n"); }
    405396
    406397        // Find the next thread(s) to run
     
    477468        monitor_ctx( this.monitors, this.monitor_count );
    478469
    479         verify( disable_preempt_count == 0 );
    480 
    481470        // Lock all monitors (aggregates the locks them as well)
    482471        lock_all( monitors, locks, count );
    483 
    484         // verify( disable_preempt_count == count );
    485         if(disable_preempt_count != count) { __cfaabi_dbg_print_buffer_decl("----------Gonna crash\n"); }
    486472
    487473
  • src/libcfa/concurrency/preemption.c

    re76bd39 rd0a045c  
    142142        // Disable interrupts by incrementing the counter
    143143        void disable_interrupts() {
    144                 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );
     144                preemption_enabled = false;
     145                __attribute__((unused)) unsigned short new_val = disable_preempt_count + 1;
     146                disable_preempt_count = new_val;
    145147                verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
    146148        }
     
    152154                thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
    153155
    154                 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     156                unsigned short prev = disable_preempt_count;
     157                disable_preempt_count -= 1;
    155158                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
    156159
    157160                // Check if we need to prempt the thread because an interrupt was missed
    158                 if( prev == 1 && proc->pending_preemption ) {
    159                         proc->pending_preemption = false;
    160                         BlockInternal( thrd );
     161                if( prev == 1 ) {
     162                        preemption_enabled = true;
     163                        if( proc->pending_preemption ) {
     164                                proc->pending_preemption = false;
     165                                BlockInternal( thrd );
     166                        }
    161167                }
    162168
     
    168174        // Don't execute any pending CtxSwitch even if counter reaches 0
    169175        void enable_interrupts_noPoll() {
    170                 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     176                unsigned short prev = disable_preempt_count;
     177                disable_preempt_count -= 1;
    171178                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
     179                if( prev == 1 ) {
     180                        preemption_enabled = true;
     181                }
    172182        }
    173183}
     
    210220// If false : preemption is unsafe and marked as pending
    211221static inline bool preemption_ready() {
    212         bool ready = disable_preempt_count == 0 && !preemption_in_progress; // Check if preemption is safe
     222        bool ready = preemption_enabled && !preemption_in_progress; // Check if preemption is safe
    213223        this_processor->pending_preemption = !ready;                        // Adjust the pending flag accordingly
    214224        return ready;
     
    225235
    226236        // Start with preemption disabled until ready
     237        preemption_enabled = false;
    227238        disable_preempt_count = 1;
    228239
Note: See TracChangeset for help on using the changeset viewer.