Ignore:
File:
1 edited

Legend:

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

    r1f45c7d r445f984  
    2222#include <errno.h>
    2323#include <stdio.h>
     24#include <string.h>
    2425#include <signal.h>
    2526#include <unistd.h>
     
    3132#include "kernel_private.hfa"
    3233#include "preemption.hfa"
     34#include "strstream.hfa"
     35#include "device/cpu.hfa"
    3336
    3437//Private includes
     
    110113#endif
    111114
    112 extern $thread * mainThread;
     115extern thread$ * mainThread;
    113116extern processor * mainProcessor;
    114117
    115118//-----------------------------------------------------------------------------
    116119// Kernel Scheduling logic
    117 static $thread * __next_thread(cluster * this);
    118 static $thread * __next_thread_slow(cluster * this);
    119 static inline bool __must_unpark( $thread * thrd ) __attribute((nonnull(1)));
    120 static void __run_thread(processor * this, $thread * dst);
     120static thread$ * __next_thread(cluster * this);
     121static thread$ * __next_thread_slow(cluster * this);
     122static inline bool __must_unpark( thread$ * thrd ) __attribute((nonnull(1)));
     123static void __run_thread(processor * this, thread$ * dst);
    121124static void __wake_one(cluster * cltr);
    122125
     
    181184                __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this);
    182185
    183                 $thread * readyThread = 0p;
     186                thread$ * readyThread = 0p;
    184187                MAIN_LOOP:
    185188                for() {
     
    231234                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
    232235
    233                                 __disable_interrupts_hard();
    234                                 eventfd_t val;
    235                                 eventfd_read( this->idle, &val );
    236                                 __enable_interrupts_hard();
     236                                {
     237                                        eventfd_t val;
     238                                        ssize_t ret = read( this->idle, &val, sizeof(val) );
     239                                        if(ret < 0) {
     240                                                switch((int)errno) {
     241                                                case EAGAIN:
     242                                                #if EAGAIN != EWOULDBLOCK
     243                                                        case EWOULDBLOCK:
     244                                                #endif
     245                                                case EINTR:
     246                                                        // No need to do anything special here, just assume it's a legitimate wake-up
     247                                                        break;
     248                                                default:
     249                                                        abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     250                                                }
     251                                        }
     252                                }
    237253
    238254                                #if !defined(__CFA_NO_STATISTICS__)
     
    388404// runThread runs a thread by context switching
    389405// from the processor coroutine to the target thread
    390 static void __run_thread(processor * this, $thread * thrd_dst) {
     406static void __run_thread(processor * this, thread$ * thrd_dst) {
    391407        /* paranoid */ verify( ! __preemption_enabled() );
    392408        /* paranoid */ verifyf( thrd_dst->state == Ready || thrd_dst->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", thrd_dst->state, thrd_dst->preempted);
     
    406422        __cfadbg_print_safe(runtime_core, "Kernel : core %p running thread %p (%s)\n", this, thrd_dst, thrd_dst->self_cor.name);
    407423
    408         $coroutine * proc_cor = get_coroutine(this->runner);
     424        coroutine$ * proc_cor = get_coroutine(this->runner);
    409425
    410426        // set state of processor coroutine to inactive
     
    425441                /* paranoid */ verify( thrd_dst->context.SP );
    426442                /* paranoid */ verify( thrd_dst->state != Halted );
    427                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
    428                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
     443                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
     444                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
    429445                /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd_dst->canary );
    430446
     
    438454
    439455                /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd_dst->canary );
    440                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->corctx_flag, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
    441                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->corctx_flag, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
     456                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
     457                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
    442458                /* paranoid */ verify( thrd_dst->context.SP );
    443459                /* paranoid */ verify( thrd_dst->curr_cluster == this->cltr );
     
    505521void returnToKernel() {
    506522        /* paranoid */ verify( ! __preemption_enabled() );
    507         $coroutine * proc_cor = get_coroutine(kernelTLS().this_processor->runner);
    508         $thread * thrd_src = kernelTLS().this_thread;
     523        coroutine$ * proc_cor = get_coroutine(kernelTLS().this_processor->runner);
     524        thread$ * thrd_src = kernelTLS().this_thread;
    509525
    510526        __STATS( thrd_src->last_proc = kernelTLS().this_processor; )
     
    534550
    535551        /* paranoid */ verify( ! __preemption_enabled() );
    536         /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) < ((uintptr_t)__get_stack(thrd_src->curr_cor)->base ) || thrd_src->corctx_flag, "ERROR : Returning $thread %p has been corrupted.\n StackPointer too small.\n", thrd_src );
    537         /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) > ((uintptr_t)__get_stack(thrd_src->curr_cor)->limit) || thrd_src->corctx_flag, "ERROR : Returning $thread %p has been corrupted.\n StackPointer too large.\n", thrd_src );
     552        /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) < ((uintptr_t)__get_stack(thrd_src->curr_cor)->base ) || thrd_src->corctx_flag, "ERROR : Returning thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_src );
     553        /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) > ((uintptr_t)__get_stack(thrd_src->curr_cor)->limit) || thrd_src->corctx_flag, "ERROR : Returning thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_src );
    538554}
    539555
     
    541557// Scheduler routines
    542558// KERNEL ONLY
    543 static void __schedule_thread( $thread * thrd ) {
     559static void __schedule_thread( thread$ * thrd ) {
    544560        /* paranoid */ verify( ! __preemption_enabled() );
    545561        /* paranoid */ verify( ready_schedule_islocked());
     
    589605}
    590606
    591 void schedule_thread$( $thread * thrd ) {
     607void schedule_thread$( thread$ * thrd ) {
    592608        ready_schedule_lock();
    593609                __schedule_thread( thrd );
     
    596612
    597613// KERNEL ONLY
    598 static inline $thread * __next_thread(cluster * this) with( *this ) {
     614static inline thread$ * __next_thread(cluster * this) with( *this ) {
    599615        /* paranoid */ verify( ! __preemption_enabled() );
    600616
    601617        ready_schedule_lock();
    602                 $thread * thrd = pop_fast( this );
     618                thread$ * thrd = pop_fast( this );
    603619        ready_schedule_unlock();
    604620
     
    608624
    609625// KERNEL ONLY
    610 static inline $thread * __next_thread_slow(cluster * this) with( *this ) {
     626static inline thread$ * __next_thread_slow(cluster * this) with( *this ) {
    611627        /* paranoid */ verify( ! __preemption_enabled() );
    612628
    613629        ready_schedule_lock();
    614                 $thread * thrd;
     630                thread$ * thrd;
    615631                for(25) {
    616632                        thrd = pop_slow( this );
     
    626642}
    627643
    628 static inline bool __must_unpark( $thread * thrd ) {
     644static inline bool __must_unpark( thread$ * thrd ) {
    629645        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    630646        switch(old_ticket) {
     
    642658}
    643659
    644 void __kernel_unpark( $thread * thrd ) {
     660void __kernel_unpark( thread$ * thrd ) {
    645661        /* paranoid */ verify( ! __preemption_enabled() );
    646662        /* paranoid */ verify( ready_schedule_islocked());
     
    657673}
    658674
    659 void unpark( $thread * thrd ) {
     675void unpark( thread$ * thrd ) {
    660676        if( !thrd ) return;
    661677
     
    681697        // Should never return
    682698        void __cfactx_thrd_leave() {
    683                 $thread * thrd = active_thread();
    684                 $monitor * this = &thrd->self_mon;
     699                thread$ * thrd = active_thread();
     700                monitor$ * this = &thrd->self_mon;
    685701
    686702                // Lock the monitor now
     
    694710                /* paranoid */ verify( kernelTLS().this_thread == thrd );
    695711                /* paranoid */ verify( thrd->context.SP );
    696                 /* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) > ((uintptr_t)__get_stack(thrd->curr_cor)->limit), "ERROR : $thread %p has been corrupted.\n StackPointer too large.\n", thrd );
    697                 /* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) < ((uintptr_t)__get_stack(thrd->curr_cor)->base ), "ERROR : $thread %p has been corrupted.\n StackPointer too small.\n", thrd );
     712                /* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) > ((uintptr_t)__get_stack(thrd->curr_cor)->limit), "ERROR : thread$ %p has been corrupted.\n StackPointer too large.\n", thrd );
     713                /* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) < ((uintptr_t)__get_stack(thrd->curr_cor)->base ), "ERROR : thread$ %p has been corrupted.\n StackPointer too small.\n", thrd );
    698714
    699715                thrd->state = Halting;
     
    713729bool force_yield( __Preemption_Reason reason ) {
    714730        __disable_interrupts_checked();
    715                 $thread * thrd = kernelTLS().this_thread;
     731                thread$ * thrd = kernelTLS().this_thread;
    716732                /* paranoid */ verify(thrd->state == Active);
    717733
     
    825841//=============================================================================================
    826842void __kernel_abort_msg( char * abort_text, int abort_text_size ) {
    827         $thread * thrd = __cfaabi_tls.this_thread;
     843        thread$ * thrd = __cfaabi_tls.this_thread;
    828844
    829845        if(thrd) {
Note: See TracChangeset for help on using the changeset viewer.