Ignore:
File:
1 edited

Legend:

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

    rf586539 r8e16177  
    1515
    1616#define __cforall_thread__
     17// #define __CFA_DEBUG_PRINT_RUNTIME_CORE__
    1718
    1819//C Includes
     
    4041#include "invoke.h"
    4142
     43
    4244//-----------------------------------------------------------------------------
    4345// Some assembly required
     
    230232        idle{};
    231233
    232         __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", &this);
     234        __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
    233235
    234236        this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    235237
    236         __cfaabi_dbg_print_safe("Kernel : core %p started\n", &this);
     238        __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this);
    237239}
    238240
    239241void ^?{}(processor & this) with( this ){
    240242        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
    241                 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
     243                __cfadbg_print_safe(runtime_core, "Kernel : core %p signaling termination\n", &this);
    242244
    243245                __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED);
     
    248250        }
    249251
    250         pthread_join( kernel_thread, 0p );
     252        int err = pthread_join( kernel_thread, 0p );
     253        if( err != 0 ) abort("KERNEL ERROR: joining processor %p caused error %s\n", &this, strerror(err));
     254
    251255        free( this.stack );
    252256}
    253257
    254 void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) {
     258void ?{}(cluster & this, const char name[], Duration preemption_rate, int io_flags) with( this ) {
    255259        this.name = name;
    256260        this.preemption_rate = preemption_rate;
     
    258262        ready_queue_lock{};
    259263
     264        #if !defined(__CFA_NO_STATISTICS__)
     265                print_stats = false;
     266        #endif
     267
    260268        procs{ __get };
    261269        idles{ __get };
    262270        threads{ __get };
    263271
     272        __kernel_io_startup( this, io_flags, &this == mainCluster );
     273
    264274        doregister(this);
    265275}
    266276
    267277void ^?{}(cluster & this) {
     278        __kernel_io_shutdown( this, &this == mainCluster );
     279
    268280        unregister(this);
    269281}
     
    281293        verify(this);
    282294
    283         __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
     295        __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
    284296
    285297        doregister(this->cltr, this);
     
    289301                preemption_scope scope = { this };
    290302
    291                 __cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
     303                __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this);
    292304
    293305                $thread * readyThread = 0p;
     
    315327                }
    316328
    317                 __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this);
     329                __cfadbg_print_safe(runtime_core, "Kernel : core %p stopping\n", this);
    318330        }
    319331
     
    322334        V( this->terminated );
    323335
    324         __cfaabi_dbg_print_safe("Kernel : core %p terminated\n", this);
     336        __cfadbg_print_safe(runtime_core, "Kernel : core %p terminated\n", this);
    325337
    326338        // HACK : the coroutine context switch expects this_thread to be set
     
    467479
    468480        //We now have a proper context from which to schedule threads
    469         __cfaabi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx);
     481        __cfadbg_print_safe(runtime_core, "Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx);
    470482
    471483        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
     
    478490
    479491        // Main routine of the core returned, the core is now fully terminated
    480         __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, &proc->runner);
     492        __cfadbg_print_safe(runtime_core, "Kernel : core %p main ended (%p)\n", proc, &proc->runner);
    481493
    482494        return 0p;
     
    611623}
    612624
    613 void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
    614         if( !thrd ) return;
    615 
    616         disable_interrupts();
     625// KERNEL ONLY unpark with out disabling interrupts
     626void __unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
    617627        static_assert(sizeof(thrd->state) == sizeof(int));
    618628
     
    643653                        abort();
    644654        }
     655}
     656
     657void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
     658        if( !thrd ) return;
     659
     660        disable_interrupts();
     661        __unpark( thrd __cfaabi_dbg_ctx_fwd2 );
    645662        enable_interrupts( __cfaabi_dbg_ctx );
    646663}
     
    704721static void __kernel_startup(void) {
    705722        verify( ! kernelTLS.preemption_state.enabled );
    706         __cfaabi_dbg_print_safe("Kernel : Starting\n");
     723        __cfadbg_print_safe(runtime_core, "Kernel : Starting\n");
    707724
    708725        __page_size = sysconf( _SC_PAGESIZE );
     
    715732        (*mainCluster){"Main Cluster"};
    716733
    717         __cfaabi_dbg_print_safe("Kernel : Main cluster ready\n");
     734        __cfadbg_print_safe(runtime_core, "Kernel : Main cluster ready\n");
    718735
    719736        // Start by initializing the main thread
     
    725742        (*mainThread){ &info };
    726743
    727         __cfaabi_dbg_print_safe("Kernel : Main thread ready\n");
     744        __cfadbg_print_safe(runtime_core, "Kernel : Main thread ready\n");
    728745
    729746
     
    746763
    747764                runner{ &this };
    748                 __cfaabi_dbg_print_safe("Kernel : constructed main processor context %p\n", &runner);
     765                __cfadbg_print_safe(runtime_core, "Kernel : constructed main processor context %p\n", &runner);
    749766        }
    750767
     
    771788
    772789
    773 
    774790        // THE SYSTEM IS NOW COMPLETELY RUNNING
    775         __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
     791
     792
     793        // Now that the system is up, finish creating systems that need threading
     794        __kernel_io_finish_start( *mainCluster );
     795
     796
     797        __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n");
    776798
    777799        verify( ! kernelTLS.preemption_state.enabled );
     
    781803
    782804static void __kernel_shutdown(void) {
    783         __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
     805        //Before we start shutting things down, wait for systems that need threading to shutdown
     806        __kernel_io_prepare_stop( *mainCluster );
    784807
    785808        /* paranoid */ verify( TL_GET( preemption_state.enabled ) );
    786809        disable_interrupts();
    787810        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     811
     812        __cfadbg_print_safe(runtime_core, "\n--------------------------------------------------\nKernel : Shutting down\n");
    788813
    789814        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    801826        // Destroy the main processor and its context in reverse order of construction
    802827        // These were manually constructed so we need manually destroy them
     828        void ^?{}(processor & this) with( this ){
     829                /* paranoid */ verify( this.do_terminate == true );
     830        }
     831
    803832        ^(*mainProcessor){};
    804833
     
    808837        ^(*mainThread){};
    809838
     839        ^(*mainCluster){};
     840
    810841        ^(__cfa_dbg_global_clusters.list){};
    811842        ^(__cfa_dbg_global_clusters.lock){};
    812843
    813         __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
     844        __cfadbg_print_safe(runtime_core, "Kernel : Shutdown complete\n");
    814845}
    815846
     
    836867
    837868        // We are ready to sleep
    838         __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
     869        __cfadbg_print_safe(runtime_core, "Kernel : Processor %p ready to sleep\n", this);
    839870        wait( idle );
    840871
    841872        // We have woken up
    842         __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     873        __cfadbg_print_safe(runtime_core, "Kernel : Processor %p woke up and ready to run\n", this);
    843874
    844875        // Get ourself off the idle list
     
    856887static bool __wake_one(cluster * this, __attribute__((unused)) bool force) {
    857888        // if we don't want to force check if we know it's false
    858         if( !this->idles.head && !force ) return false;
     889        // if( !this->idles.head && !force ) return false;
    859890
    860891        // First, lock the cluster idle
     
    869900
    870901        // Wake them up
     902        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this->idles.head);
     903        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    871904        post( this->idles.head->idle );
    872905
     
    878911// Unconditionnaly wake a thread
    879912static bool __wake_proc(processor * this) {
    880         return post( this->idle );
     913        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
     914
     915        disable_interrupts();
     916                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     917                bool ret = post( this->idle );
     918        enable_interrupts( __cfaabi_dbg_ctx );
     919
     920        return ret;
    881921}
    882922
     
    9601000void ^?{}(semaphore & this) {}
    9611001
    962 void P(semaphore & this) with( this ){
     1002bool P(semaphore & this) with( this ){
    9631003        lock( lock __cfaabi_dbg_ctx2 );
    9641004        count -= 1;
     
    9701010                unlock( lock );
    9711011                park( __cfaabi_dbg_ctx );
     1012                return true;
    9721013        }
    9731014        else {
    9741015            unlock( lock );
     1016            return false;
    9751017        }
    9761018}
     
    9891031        // make new owner
    9901032        unpark( thrd __cfaabi_dbg_ctx2 );
     1033
     1034        return thrd != 0p;
     1035}
     1036
     1037bool V(semaphore & this, unsigned diff) with( this ) {
     1038        $thread * thrd = 0p;
     1039        lock( lock __cfaabi_dbg_ctx2 );
     1040        int release = max(-count, (int)diff);
     1041        count += diff;
     1042        for(release) {
     1043                unpark( pop_head( waiting ) __cfaabi_dbg_ctx2 );
     1044        }
     1045
     1046        unlock( lock );
    9911047
    9921048        return thrd != 0p;
Note: See TracChangeset for help on using the changeset viewer.