Ignore:
File:
1 edited

Legend:

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

    r454f478 r89eff25  
    2222extern "C" {
    2323      #include <limits.h>       // PTHREAD_STACK_MIN
     24        #include <sys/eventfd.h>  // eventfd
    2425      #include <sys/mman.h>     // mprotect
    2526      #include <sys/resource.h> // getrlimit
     
    7273static void __kernel_first_resume( processor * this );
    7374static void __kernel_last_resume ( processor * this );
    74 static void init(processor & this, const char name[], cluster & _cltr);
     75static void init(processor & this, const char name[], cluster & _cltr, $thread * initT);
    7576static void deinit(processor & this);
    7677static void doregister( struct cluster & cltr );
     
    8990extern void __kernel_alarm_startup(void);
    9091extern void __kernel_alarm_shutdown(void);
    91 extern void __kernel_io_startup (void);
    92 extern void __kernel_io_shutdown(void);
    9392
    9493//-----------------------------------------------------------------------------
     
    102101KERNEL_STORAGE($thread,              mainThread);
    103102KERNEL_STORAGE(__stack_t,            mainThreadCtx);
    104 KERNEL_STORAGE(io_context,           mainPollerThread);
    105103KERNEL_STORAGE(__scheduler_RWLock_t, __scheduler_lock);
    106104#if !defined(__CFA_NO_STATISTICS__)
     
    198196
    199197        void ?{}(processor & this) with( this ) {
    200                 ( this.idle ){};
    201198                ( this.terminated ){};
    202199                ( this.runner ){};
    203                 init( this, "Main Processor", *mainCluster );
     200                init( this, "Main Processor", *mainCluster, 0p );
    204201                kernel_thread = pthread_self();
    205202
     
    226223        __kernel_alarm_startup();
    227224
    228         // Start IO
    229         __kernel_io_startup();
    230 
    231225        // Add the main thread to the ready queue
    232226        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
     
    241235        // THE SYSTEM IS NOW COMPLETELY RUNNING
    242236
    243 
    244         // SKULLDUGGERY: The constructor for the mainCluster will call alloc with a dimension of 0
    245         // malloc *can* return a non-null value, we should free it if that is the case
    246         free( mainCluster->io.ctxs );
    247 
    248         // Now that the system is up, finish creating systems that need threading
    249         mainCluster->io.ctxs = (io_context *)&storage_mainPollerThread;
    250         mainCluster->io.cnt  = 1;
    251         (*mainCluster->io.ctxs){ *mainCluster };
    252 
    253237        __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n");
    254238
     
    260244
    261245static void __kernel_shutdown(void) {
    262         //Before we start shutting things down, wait for systems that need threading to shutdown
    263         ^(*mainCluster->io.ctxs){};
    264         mainCluster->io.cnt  = 0;
    265         mainCluster->io.ctxs = 0p;
    266 
    267246        /* paranoid */ verify( __preemption_enabled() );
    268247        disable_interrupts();
     
    283262        __kernel_alarm_shutdown();
    284263
    285         // Stop IO
    286         __kernel_io_shutdown();
     264        #if !defined( __CFA_NO_STATISTICS__ )
     265                __stats_t * st = (__stats_t *)& storage_mainProcStats;
     266                __tally_stats(mainCluster->stats, st);
     267                if( 0 != mainProcessor->print_stats ) {
     268                        __print_stats( st, mainProcessor->print_stats, "Processor ", mainProcessor->name, (void*)mainProcessor );
     269                }
     270                #if defined(CFA_STATS_ARRAY)
     271                        __flush_stat( st, "Processor", mainProcessor );
     272                #endif
     273        #endif
    287274
    288275        // Destroy the main processor and its context in reverse order of construction
     
    364351                        __print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc );
    365352                }
     353                #if defined(CFA_STATS_ARRAY)
     354                        __flush_stat( &local_stats, "Processor", proc );
     355                #endif
    366356        #endif
    367357
     
    457447        link.next = 0p;
    458448        link.prev = 0p;
     449        link.preferred = -1u;
     450        last_proc = 0p;
    459451        #if defined( __CFA_WITH_VERIFY__ )
    460452                canary = 0x0D15EA5E0D15EA5Ep;
     
    476468}
    477469
    478 static void init(processor & this, const char name[], cluster & _cltr) with( this ) {
     470static void init(processor & this, const char name[], cluster & _cltr, $thread * initT) with( this ) {
    479471        this.name = name;
    480472        this.cltr = &_cltr;
    481         full_proc = true;
     473        this.rdq.its = 0;
     474        this.rdq.itr = 0;
     475        this.rdq.id  = -1u;
     476        this.rdq.target = -1u;
     477        this.rdq.cutoff = -1ull;
    482478        do_terminate = false;
    483479        preemption_alarm = 0p;
    484480        pending_preemption = false;
    485481
     482        this.io.ctx = 0p;
     483        this.io.pending = false;
     484        this.io.dirty   = false;
     485
     486        this.init.thrd = initT;
     487
     488        this.idle = eventfd(0, 0);
     489        if (idle < 0) {
     490                abort("KERNEL ERROR: PROCESSOR EVENTFD - %s\n", strerror(errno));
     491        }
     492
    486493        #if !defined(__CFA_NO_STATISTICS__)
    487494                print_stats = 0;
     
    489496        #endif
    490497
    491         lock( this.cltr->idles );
    492                 int target = this.cltr->idles.total += 1u;
    493         unlock( this.cltr->idles );
    494 
    495         id = doregister((__processor_id_t*)&this);
    496 
     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
     509        __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this);
     510}
     511
     512// Not a ctor, it just preps the destruction but should not destroy members
     513static void deinit(processor & this) {
    497514        // Lock the RWlock so no-one pushes/pops while we are changing the queue
    498515        uint_fast32_t last_size = ready_mutate_lock();
     516                this.cltr->procs.total -= 1u;
     517                remove(this);
    499518
    500519                // Adjust the ready queue size
    501                 ready_queue_grow( cltr, target );
    502 
    503         // Unlock the RWlock
    504         ready_mutate_unlock( last_size );
    505 
    506         __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this);
    507 }
    508 
    509 // Not a ctor, it just preps the destruction but should not destroy members
    510 static void deinit(processor & this) {
    511         lock( this.cltr->idles );
    512                 int target = this.cltr->idles.total -= 1u;
    513         unlock( this.cltr->idles );
    514 
    515         // Lock the RWlock so no-one pushes/pops while we are changing the queue
    516         uint_fast32_t last_size = ready_mutate_lock();
    517 
    518                 // Adjust the ready queue size
    519                 ready_queue_shrink( this.cltr, target );
    520 
    521         // Unlock the RWlock
    522         ready_mutate_unlock( last_size );
    523 
    524         // Finally we don't need the read_lock any more
    525         unregister((__processor_id_t*)&this);
    526 }
    527 
    528 void ?{}(processor & this, const char name[], cluster & _cltr) {
    529         ( this.idle ){};
     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
     525        close(this.idle);
     526}
     527
     528void ?{}(processor & this, const char name[], cluster & _cltr, $thread * initT) {
    530529        ( this.terminated ){};
    531530        ( this.runner ){};
    532531
    533532        disable_interrupts();
    534                 init( this, name, _cltr );
     533                init( this, name, _cltr, initT );
    535534        enable_interrupts( __cfaabi_dbg_ctx );
    536535
     
    538537
    539538        this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    540 
     539}
     540
     541void ?{}(processor & this, const char name[], cluster & _cltr) {
     542        (this){name, _cltr, 0p};
    541543}
    542544
     
    562564//-----------------------------------------------------------------------------
    563565// Cluster
    564 static void ?{}(__cluster_idles & this) {
     566static void ?{}(__cluster_proc_list & this) {
    565567        this.lock  = 0;
    566568        this.idle  = 0;
    567569        this.total = 0;
    568         (this.list){};
    569570}
    570571
     
    582583        threads{ __get };
    583584
     585        io.arbiter = create();
     586        io.params = io_params;
     587
    584588        doregister(this);
    585589
     
    589593
    590594                // Adjust the ready queue size
    591                 ready_queue_grow( &this, 0 );
     595                ready_queue_grow( &this );
    592596
    593597        // Unlock the RWlock
    594598        ready_mutate_unlock( last_size );
    595599        enable_interrupts_noPoll(); // Don't poll, could be in main cluster
    596 
    597 
    598         this.io.cnt  = num_io;
    599         this.io.ctxs = aalloc(num_io);
    600         for(i; this.io.cnt) {
    601                 (this.io.ctxs[i]){ this, io_params };
    602         }
    603600}
    604601
    605602void ^?{}(cluster & this) {
    606         for(i; this.io.cnt) {
    607                 ^(this.io.ctxs[i]){ true };
    608         }
    609         free(this.io.ctxs);
     603        destroy(this.io.arbiter);
    610604
    611605        // Lock the RWlock so no-one pushes/pops while we are changing the queue
     
    614608
    615609                // Adjust the ready queue size
    616                 ready_queue_shrink( &this, 0 );
     610                ready_queue_shrink( &this );
    617611
    618612        // Unlock the RWlock
     
    624618                        __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this );
    625619                }
     620                #if defined(CFA_STATS_ARRAY)
     621                        __flush_stat( this.stats, "Cluster", &this );
     622                #endif
    626623                free( this.stats );
    627624        #endif
     
    736733}
    737734
    738 
    739735#if defined(__CFA_WITH_VERIFY__)
    740736static bool verify_fwd_bck_rng(void) {
Note: See TracChangeset for help on using the changeset viewer.