Ignore:
Timestamp:
Jun 27, 2018, 3:28:41 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
b21c77a
Parents:
0182bfa (diff), 63238a4 (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' into with_gc

File:
1 edited

Legend:

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

    r0182bfa r28f3a19  
    1616//C Includes
    1717#include <stddef.h>
     18#include <errno.h>
     19#include <string.h>
    1820extern "C" {
    1921#include <stdio.h>
     
    4951thread_desc * mainThread;
    5052
    51 struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
     53extern "C" {
     54struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters;
     55}
    5256
    5357//-----------------------------------------------------------------------------
     
    143147        runner.proc = &this;
    144148
     149        idleLock{};
     150
    145151        start( &this );
    146152}
    147153
    148154void ^?{}(processor & this) with( this ){
    149         if( ! do_terminate ) {
     155        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
    150156                __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
    151                 terminate(&this);
    152                 verify(this.do_terminate);
    153                 verify( kernelTLS.this_processor != &this);
     157
     158                __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED);
     159                wake( &this );
     160
    154161                P( terminated );
    155162                verify( kernelTLS.this_processor != &this);
    156                 pthread_join( kernel_thread, NULL );
    157         }
     163        }
     164
     165        pthread_join( kernel_thread, NULL );
    158166}
    159167
     
    194202
    195203                thread_desc * readyThread = NULL;
    196                 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ )
     204                for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ )
    197205                {
    198206                        readyThread = nextThread( this->cltr );
     
    213221                        else
    214222                        {
    215                                 spin(this, &spin_count);
     223                                // spin(this, &spin_count);
     224                                halt(this);
    216225                        }
    217226                }
     
    257266// its final actions must be executed from the kernel
    258267void finishRunning(processor * this) with( this->finish ) {
    259         if( action_code == Release ) {
    260                 verify( ! kernelTLS.preemption_state.enabled );
     268        verify( ! kernelTLS.preemption_state.enabled );
     269        choose( action_code ) {
     270        case No_Action:
     271                break;
     272        case Release:
    261273                unlock( *lock );
    262         }
    263         else if( action_code == Schedule ) {
     274        case Schedule:
    264275                ScheduleThread( thrd );
    265         }
    266         else if( action_code == Release_Schedule ) {
    267                 verify( ! kernelTLS.preemption_state.enabled );
     276        case Release_Schedule:
    268277                unlock( *lock );
    269278                ScheduleThread( thrd );
    270         }
    271         else if( action_code == Release_Multi ) {
    272                 verify( ! kernelTLS.preemption_state.enabled );
     279        case Release_Multi:
    273280                for(int i = 0; i < lock_count; i++) {
    274281                        unlock( *locks[i] );
    275282                }
    276         }
    277         else if( action_code == Release_Multi_Schedule ) {
     283        case Release_Multi_Schedule:
    278284                for(int i = 0; i < lock_count; i++) {
    279285                        unlock( *locks[i] );
     
    282288                        ScheduleThread( thrds[i] );
    283289                }
    284         }
    285         else {
    286                 assert(action_code == No_Action);
    287         }
    288 }
    289 
    290 // Handles spinning logic
    291 // TODO : find some strategy to put cores to sleep after some time
    292 void spin(processor * this, unsigned int * spin_count) {
    293         (*spin_count)++;
     290        case Callback:
     291                callback();
     292        default:
     293                abort("KERNEL ERROR: Unexpected action to run after thread");
     294        }
    294295}
    295296
     
    396397        with( *thrd->curr_cluster ) {
    397398                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
     399                bool was_empty = !(ready_queue != 0);
    398400                append( ready_queue, thrd );
    399401                unlock( ready_queue_lock );
     402
     403                if(was_empty) {
     404                        lock      (proc_list_lock __cfaabi_dbg_ctx2);
     405                        if(idles) {
     406                                wake_fast(idles.head);
     407                        }
     408                        unlock    (proc_list_lock);
     409                }
     410                else if( struct processor * idle = idles.head ) {
     411                        wake_fast(idle);
     412                }
     413
    400414        }
    401415
     
    497511}
    498512
     513void BlockInternal(__finish_callback_fptr_t callback) {
     514        disable_interrupts();
     515        with( *kernelTLS.this_processor ) {
     516                finish.action_code = Callback;
     517                finish.callback    = callback;
     518        }
     519
     520        verify( ! kernelTLS.preemption_state.enabled );
     521        returnToKernel();
     522        verify( ! kernelTLS.preemption_state.enabled );
     523
     524        enable_interrupts( __cfaabi_dbg_ctx );
     525}
     526
    499527// KERNEL ONLY
    500528void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
     
    518546        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    519547
    520         global_clusters.list{ __get };
    521         global_clusters.lock{};
     548        __cfa_dbg_global_clusters.list{ __get };
     549        __cfa_dbg_global_clusters.lock{};
    522550
    523551        // Initialize the main cluster
     
    600628        // When its coroutine terminates, it return control to the mainThread
    601629        // which is currently here
    602         mainProcessor->do_terminate = true;
     630        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    603631        returnToKernel();
     632        mainThread->self_cor.state = Halted;
    604633
    605634        // THE SYSTEM IS NOW COMPLETELY STOPPED
     
    617646        ^(mainThread){};
    618647
    619         ^(global_clusters.list){};
    620         ^(global_clusters.lock){};
     648        ^(__cfa_dbg_global_clusters.list){};
     649        ^(__cfa_dbg_global_clusters.lock){};
    621650
    622651        __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
     
    627656//=============================================================================================
    628657
    629 // void halt(processor * this) with( this ) {
    630 //      pthread_mutex_lock( &idle.lock );
    631 
    632 
    633 
    634 //      // SKULLDUGGERY: Even if spurious wake-up is a thing
    635 //      // spuriously waking up a kernel thread is not a big deal
    636 //      // if it is very rare.
    637 //      pthread_cond_wait( &idle.cond, &idle.lock);
    638 //      pthread_mutex_unlock( &idle.lock );
    639 // }
    640 
    641 // void wake(processor * this) with( this ) {
    642 //      pthread_mutex_lock  (&idle.lock);
    643 //      pthread_cond_signal (&idle.cond);
    644 //      pthread_mutex_unlock(&idle.lock);
    645 // }
     658void halt(processor * this) with( *this ) {
     659        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
     660
     661        with( *cltr ) {
     662                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     663                remove    (procs, *this);
     664                push_front(idles, *this);
     665                unlock    (proc_list_lock);
     666        }
     667
     668        __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
     669
     670        wait( idleLock );
     671
     672        __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     673
     674        with( *cltr ) {
     675                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     676                remove    (idles, *this);
     677                push_front(procs, *this);
     678                unlock    (proc_list_lock);
     679        }
     680}
    646681
    647682//=============================================================================================
     
    758793// Global Queues
    759794void doregister( cluster     & cltr ) {
    760         lock      ( global_clusters.lock __cfaabi_dbg_ctx2);
    761         push_front( global_clusters.list, cltr );
    762         unlock    ( global_clusters.lock );
     795        lock      ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2);
     796        push_front( __cfa_dbg_global_clusters.list, cltr );
     797        unlock    ( __cfa_dbg_global_clusters.lock );
    763798}
    764799
    765800void unregister( cluster     & cltr ) {
    766         lock  ( global_clusters.lock __cfaabi_dbg_ctx2);
    767         remove( global_clusters.list, cltr );
    768         unlock( global_clusters.lock );
     801        lock  ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2);
     802        remove( __cfa_dbg_global_clusters.list, cltr );
     803        unlock( __cfa_dbg_global_clusters.lock );
    769804}
    770805
Note: See TracChangeset for help on using the changeset viewer.