Ignore:
Timestamp:
Apr 29, 2021, 4:26:25 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:
3eb55f98
Parents:
b2fc7ad9
Message:

Changed RW lock to avoid hitting the global array on schedule.

Location:
libcfa/src/concurrency/kernel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/fwd.hfa

    rb2fc7ad9 rc993b15  
    3838                        struct $thread          * volatile this_thread;
    3939                        struct processor        * volatile this_processor;
    40                         struct __processor_id_t * volatile this_proc_id;
    41                         struct __stats_t        * volatile this_stats;
     40                        volatile bool sched_lock;
    4241
    4342                        struct {
     
    5655                                uint64_t bck_seed;
    5756                        } ready_rng;
     57
     58                        struct __stats_t        * volatile this_stats;
     59
     60
     61                        #ifdef __CFA_WITH_VERIFY__
     62                                // Debug, check if the rwlock is owned for reading
     63                                bool in_sched_lock;
     64                                unsigned sched_id;
     65                        #endif
    5866                } __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" )));
    5967
  • libcfa/src/concurrency/kernel/startup.cfa

    rb2fc7ad9 rc993b15  
    7777static void doregister( struct cluster & cltr );
    7878static void unregister( struct cluster & cltr );
     79static void register_tls( processor * this );
     80static void unregister_tls( processor * this );
    7981static void ?{}( $coroutine & this, current_stack_info_t * info);
    8082static void ?{}( $thread & this, current_stack_info_t * info);
     
    123125        NULL,                                                                                           // cannot use 0p
    124126        NULL,
     127        false,
     128        { 1, false, false },
     129        0,
     130        { 0, 0 },
    125131        NULL,
    126         NULL,
    127         { 1, false, false },
     132        #ifdef __CFA_WITH_VERIFY__
     133                false,
     134                0,
     135        #endif
    128136};
    129137
     
    210218        (*mainProcessor){};
    211219
     220        register_tls( mainProcessor );
     221
    212222        //initialize the global state variables
    213223        __cfaabi_tls.this_processor = mainProcessor;
    214         __cfaabi_tls.this_proc_id   = (__processor_id_t*)mainProcessor;
    215224        __cfaabi_tls.this_thread    = mainThread;
    216225
     
    273282        #endif
    274283
     284        unregister_tls( mainProcessor );
     285
    275286        // Destroy the main processor and its context in reverse order of construction
    276287        // These were manually constructed so we need manually destroy them
     
    316327        processor * proc = (processor *) arg;
    317328        __cfaabi_tls.this_processor = proc;
    318         __cfaabi_tls.this_proc_id   = (__processor_id_t*)proc;
    319329        __cfaabi_tls.this_thread    = 0p;
    320330        __cfaabi_tls.preemption_state.[enabled, disable_count] = [false, 1];
     331
     332        register_tls( proc );
     333
    321334        // SKULLDUGGERY: We want to create a context for the processor coroutine
    322335        // which is needed for the 2-step context switch. However, there is no reason
     
    355368                #endif
    356369        #endif
     370
     371        unregister_tls( proc );
    357372
    358373        return 0p;
     
    496511        #endif
    497512
    498         // Register and Lock the RWlock so no-one pushes/pops while we are changing the queue
    499         uint_fast32_t last_size = ready_mutate_register((__processor_id_t*)&this);
    500                 this.cltr->procs.total += 1u;
    501                 insert_last(this.cltr->procs.actives, this);
    502 
    503                 // Adjust the ready queue size
    504                 ready_queue_grow( cltr );
    505 
    506         // Unlock the RWlock
    507         ready_mutate_unlock( last_size );
    508 
    509513        __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this);
    510514}
     
    512516// Not a ctor, it just preps the destruction but should not destroy members
    513517static void deinit(processor & this) {
    514         // Lock the RWlock so no-one pushes/pops while we are changing the queue
    515         uint_fast32_t last_size = ready_mutate_lock();
    516                 this.cltr->procs.total -= 1u;
    517                 remove(this);
    518 
    519                 // Adjust the ready queue size
    520                 ready_queue_shrink( this.cltr );
    521 
    522         // Unlock the RWlock and unregister: we don't need the read_lock any more
    523         ready_mutate_unregister((__processor_id_t*)&this, last_size );
    524 
    525518        close(this.idle);
    526519}
     
    656649        cltr->nthreads -= 1;
    657650        unlock(cltr->thread_list_lock);
     651}
     652
     653static void register_tls( processor * this ) {
     654        // Register and Lock the RWlock so no-one pushes/pops while we are changing the queue
     655        uint_fast32_t last_size;
     656        [this->unique_id, last_size] = ready_mutate_register();
     657
     658                this->cltr->procs.total += 1u;
     659                insert_last(this->cltr->procs.actives, *this);
     660
     661                // Adjust the ready queue size
     662                ready_queue_grow( this->cltr );
     663
     664        // Unlock the RWlock
     665        ready_mutate_unlock( last_size );
     666}
     667
     668
     669static void unregister_tls( processor * this ) {
     670        // Lock the RWlock so no-one pushes/pops while we are changing the queue
     671        uint_fast32_t last_size = ready_mutate_lock();
     672                this->cltr->procs.total -= 1u;
     673                remove(*this);
     674
     675                // clear the cluster so nothing gets pushed to local queues
     676                cluster * cltr = this->cltr;
     677                this->cltr = 0p;
     678
     679                // Adjust the ready queue size
     680                ready_queue_shrink( cltr );
     681
     682        // Unlock the RWlock and unregister: we don't need the read_lock any more
     683        ready_mutate_unregister( this->unique_id, last_size );
    658684}
    659685
Note: See TracChangeset for help on using the changeset viewer.