Ignore:
Timestamp:
Apr 24, 2021, 7:45:02 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
fb0be05
Parents:
89eff25 (diff), 254ad1b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

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

    r89eff25 rcfff639  
    115115static $thread * __next_thread(cluster * this);
    116116static $thread * __next_thread_slow(cluster * this);
     117static inline bool __must_unpark( $thread * thrd ) __attribute((nonnull(1)));
    117118static void __run_thread(processor * this, $thread * dst);
    118119static void __wake_one(cluster * cltr);
     
    130131extern void __disable_interrupts_hard();
    131132extern void __enable_interrupts_hard();
     133
     134static inline void __disable_interrupts_checked() {
     135        /* paranoid */ verify( __preemption_enabled() );
     136        disable_interrupts();
     137        /* paranoid */ verify( ! __preemption_enabled() );
     138}
     139
     140static inline void __enable_interrupts_checked( bool poll = true ) {
     141        /* paranoid */ verify( ! __preemption_enabled() );
     142        enable_interrupts( poll );
     143        /* paranoid */ verify( __preemption_enabled() );
     144}
    132145
    133146//=============================================================================================
     
    452465                if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    453466                        // The thread was preempted, reschedule it and reset the flag
    454                         __schedule_thread( thrd_dst );
     467                        schedule_thread$( thrd_dst );
    455468                        break RUNNING;
    456469                }
     
    541554        /* paranoid */ verify( ! __preemption_enabled() );
    542555        /* paranoid */ verify( kernelTLS().this_proc_id );
     556        /* paranoid */ verify( ready_schedule_islocked());
    543557        /* paranoid */ verify( thrd );
    544558        /* paranoid */ verify( thrd->state != Halted );
     
    560574        __STATS(bool outside = thrd->last_proc && thrd->last_proc != kernelTLS().this_processor; )
    561575
    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();
     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 );
    571584
    572585        #if !defined(__CFA_NO_STATISTICS__)
     
    585598        #endif
    586599
    587         /* paranoid */ verify( ! __preemption_enabled() );
     600        /* paranoid */ verify( ready_schedule_islocked());
     601        /* paranoid */ verify( ! __preemption_enabled() );
     602}
     603
     604void schedule_thread$( $thread * thrd ) {
     605        ready_schedule_lock();
     606                __schedule_thread( thrd );
     607        ready_schedule_unlock();
    588608}
    589609
     
    623643}
    624644
    625 void unpark( $thread * thrd ) {
    626         if( !thrd ) return;
    627 
     645static inline bool __must_unpark( $thread * thrd ) {
    628646        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    629647        switch(old_ticket) {
    630648                case TICKET_RUNNING:
    631649                        // Wake won the race, the thread will reschedule/rerun itself
    632                         break;
     650                        return false;
    633651                case TICKET_BLOCKED:
    634652                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    635653                        /* paranoid */ verify( thrd->state == Blocked );
    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;
     654                        return true;
    653655                default:
    654656                        // This makes no sense, something is wrong abort
     
    657659}
    658660
     661void 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
    659672void park( void ) {
    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() );
     673        __disable_interrupts_checked();
     674                /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
     675                returnToKernel();
     676        __enable_interrupts_checked();
    670677
    671678}
     
    707714// KERNEL ONLY
    708715bool force_yield( __Preemption_Reason reason ) {
    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 
     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 );
    731731        return preempted;
    732732}
     
    773773        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    774774
    775         disable_interrupts();
     775        __disable_interrupts_checked();
    776776                /* paranoid */ verify( ! __preemption_enabled() );
    777777                eventfd_t val;
    778778                val = 1;
    779779                eventfd_write( this->idle, val );
    780         enable_interrupts( __cfaabi_dbg_ctx );
     780        __enable_interrupts_checked();
    781781}
    782782
Note: See TracChangeset for help on using the changeset viewer.