Ignore:
File:
1 edited

Legend:

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

    r89eff25 r454f478  
    2222extern "C" {
    2323      #include <limits.h>       // PTHREAD_STACK_MIN
    24         #include <sys/eventfd.h>  // eventfd
    2524      #include <sys/mman.h>     // mprotect
    2625      #include <sys/resource.h> // getrlimit
     
    7372static void __kernel_first_resume( processor * this );
    7473static void __kernel_last_resume ( processor * this );
    75 static void init(processor & this, const char name[], cluster & _cltr, $thread * initT);
     74static void init(processor & this, const char name[], cluster & _cltr);
    7675static void deinit(processor & this);
    7776static void doregister( struct cluster & cltr );
     
    9089extern void __kernel_alarm_startup(void);
    9190extern void __kernel_alarm_shutdown(void);
     91extern void __kernel_io_startup (void);
     92extern void __kernel_io_shutdown(void);
    9293
    9394//-----------------------------------------------------------------------------
     
    101102KERNEL_STORAGE($thread,              mainThread);
    102103KERNEL_STORAGE(__stack_t,            mainThreadCtx);
     104KERNEL_STORAGE(io_context,           mainPollerThread);
    103105KERNEL_STORAGE(__scheduler_RWLock_t, __scheduler_lock);
    104106#if !defined(__CFA_NO_STATISTICS__)
     
    196198
    197199        void ?{}(processor & this) with( this ) {
     200                ( this.idle ){};
    198201                ( this.terminated ){};
    199202                ( this.runner ){};
    200                 init( this, "Main Processor", *mainCluster, 0p );
     203                init( this, "Main Processor", *mainCluster );
    201204                kernel_thread = pthread_self();
    202205
     
    223226        __kernel_alarm_startup();
    224227
     228        // Start IO
     229        __kernel_io_startup();
     230
    225231        // Add the main thread to the ready queue
    226232        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
     
    235241        // THE SYSTEM IS NOW COMPLETELY RUNNING
    236242
     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
    237253        __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n");
    238254
     
    244260
    245261static 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
    246267        /* paranoid */ verify( __preemption_enabled() );
    247268        disable_interrupts();
     
    262283        __kernel_alarm_shutdown();
    263284
    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
     285        // Stop IO
     286        __kernel_io_shutdown();
    274287
    275288        // Destroy the main processor and its context in reverse order of construction
     
    351364                        __print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc );
    352365                }
    353                 #if defined(CFA_STATS_ARRAY)
    354                         __flush_stat( &local_stats, "Processor", proc );
    355                 #endif
    356366        #endif
    357367
     
    447457        link.next = 0p;
    448458        link.prev = 0p;
    449         link.preferred = -1u;
    450         last_proc = 0p;
    451459        #if defined( __CFA_WITH_VERIFY__ )
    452460                canary = 0x0D15EA5E0D15EA5Ep;
     
    468476}
    469477
    470 static void init(processor & this, const char name[], cluster & _cltr, $thread * initT) with( this ) {
     478static void init(processor & this, const char name[], cluster & _cltr) with( this ) {
    471479        this.name = name;
    472480        this.cltr = &_cltr;
    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;
     481        full_proc = true;
    478482        do_terminate = false;
    479483        preemption_alarm = 0p;
    480484        pending_preemption = false;
    481485
    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 
    493486        #if !defined(__CFA_NO_STATISTICS__)
    494487                print_stats = 0;
     
    496489        #endif
    497490
    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);
     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
     497        // Lock the RWlock so no-one pushes/pops while we are changing the queue
     498        uint_fast32_t last_size = ready_mutate_lock();
    502499
    503500                // Adjust the ready queue size
    504                 ready_queue_grow( cltr );
     501                ready_queue_grow( cltr, target );
    505502
    506503        // Unlock the RWlock
     
    512509// Not a ctor, it just preps the destruction but should not destroy members
    513510static void deinit(processor & this) {
     511        lock( this.cltr->idles );
     512                int target = this.cltr->idles.total -= 1u;
     513        unlock( this.cltr->idles );
     514
    514515        // Lock the RWlock so no-one pushes/pops while we are changing the queue
    515516        uint_fast32_t last_size = ready_mutate_lock();
    516                 this.cltr->procs.total -= 1u;
    517                 remove(this);
    518517
    519518                // 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 
    525         close(this.idle);
    526 }
    527 
    528 void ?{}(processor & this, const char name[], cluster & _cltr, $thread * initT) {
     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
     528void ?{}(processor & this, const char name[], cluster & _cltr) {
     529        ( this.idle ){};
    529530        ( this.terminated ){};
    530531        ( this.runner ){};
    531532
    532533        disable_interrupts();
    533                 init( this, name, _cltr, initT );
     534                init( this, name, _cltr );
    534535        enable_interrupts( __cfaabi_dbg_ctx );
    535536
     
    537538
    538539        this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    539 }
    540 
    541 void ?{}(processor & this, const char name[], cluster & _cltr) {
    542         (this){name, _cltr, 0p};
     540
    543541}
    544542
     
    564562//-----------------------------------------------------------------------------
    565563// Cluster
    566 static void ?{}(__cluster_proc_list & this) {
     564static void ?{}(__cluster_idles & this) {
    567565        this.lock  = 0;
    568566        this.idle  = 0;
    569567        this.total = 0;
     568        (this.list){};
    570569}
    571570
     
    583582        threads{ __get };
    584583
    585         io.arbiter = create();
    586         io.params = io_params;
    587 
    588584        doregister(this);
    589585
     
    593589
    594590                // Adjust the ready queue size
    595                 ready_queue_grow( &this );
     591                ready_queue_grow( &this, 0 );
    596592
    597593        // Unlock the RWlock
    598594        ready_mutate_unlock( last_size );
    599595        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        }
    600603}
    601604
    602605void ^?{}(cluster & this) {
    603         destroy(this.io.arbiter);
     606        for(i; this.io.cnt) {
     607                ^(this.io.ctxs[i]){ true };
     608        }
     609        free(this.io.ctxs);
    604610
    605611        // Lock the RWlock so no-one pushes/pops while we are changing the queue
     
    608614
    609615                // Adjust the ready queue size
    610                 ready_queue_shrink( &this );
     616                ready_queue_shrink( &this, 0 );
    611617
    612618        // Unlock the RWlock
     
    618624                        __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this );
    619625                }
    620                 #if defined(CFA_STATS_ARRAY)
    621                         __flush_stat( this.stats, "Cluster", &this );
    622                 #endif
    623626                free( this.stats );
    624627        #endif
     
    733736}
    734737
     738
    735739#if defined(__CFA_WITH_VERIFY__)
    736740static bool verify_fwd_bck_rng(void) {
Note: See TracChangeset for help on using the changeset viewer.