Ignore:
Timestamp:
Jun 16, 2017, 4:45:20 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
ec35498
Parents:
70c2df8
Message:

Preemption with some bug fixes and much more debugging, still not working at 100%

Location:
src/libcfa/concurrency
Files:
8 edited

Legend:

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

    r70c2df8 r4e6fb8e  
    8989}
    9090
     91LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {
     92        alarm_node_t ** it = &this->head;
     93        while( (*it) ) {
     94                it = &(*it)->next;
     95        }
     96
     97        return it == this->tail;
     98})
     99
    91100static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) {
    92101        assert( !n->next );
     
    98107        }
    99108        *p = n;
     109
     110        LIB_DEBUG_DO( assert( validate( this ) ) );
    100111}
    101112
     
    107118
    108119        insert_at( this, n, it );
     120
     121        LIB_DEBUG_DO( assert( validate( this ) ) );
    109122}
    110123
     
    118131                head->next = NULL;
    119132        }
     133        LIB_DEBUG_DO( assert( validate( this ) ) );
    120134        return head;
    121135}
     
    123137static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) {
    124138        assert( it );
    125         assert( (*it)->next == n );
    126 
    127         (*it)->next = n->next;
     139        assert( (*it) == n );
     140
     141        (*it) = n->next;
    128142        if( !n-> next ) {
    129143                this->tail = it;
    130144        }
    131145        n->next = NULL;
     146
     147        LIB_DEBUG_DO( assert( validate( this ) ) );
    132148}
    133149
    134150static inline void remove( alarm_list_t * this, alarm_node_t * n ) {
    135151        alarm_node_t ** it = &this->head;
    136         while( (*it) && (*it)->next != n ) {
     152        while( (*it) && (*it) != n ) {
    137153                it = &(*it)->next;
    138154        }
    139155
     156        LIB_DEBUG_DO( assert( validate( this ) ) );
     157
    140158        if( *it ) { remove_at( this, n, it ); }
     159
     160        LIB_DEBUG_DO( assert( validate( this ) ) );
    141161}
    142162
     
    145165        assert( !systemProcessor->pending_alarm );
    146166        lock( &systemProcessor->alarm_lock );
     167        LIB_DEBUG_DO( assert( validate( &systemProcessor->alarms ) ) );
    147168        {
    148169                bool first = !systemProcessor->alarms.head;
     
    158179        unlock( &systemProcessor->alarm_lock );
    159180        this->set = true;
    160         enable_interrupts();
     181        enable_interrupts( __PRETTY_FUNCTION__ );
    161182}
    162183
    163184void unregister_self( alarm_node_t * this ) {
     185        LIB_DEBUG_DO(
     186                char text[256];
     187                __attribute__((unused)) int len = snprintf( text, 256, "Kernel : unregister %p start\n", this );
     188                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
     189        );
    164190        disable_interrupts();
    165191        lock( &systemProcessor->alarm_lock );
     192        LIB_DEBUG_DO( assert( validate( &systemProcessor->alarms ) ) );
    166193        remove( &systemProcessor->alarms, this );
    167194        unlock( &systemProcessor->alarm_lock );
    168195        disable_interrupts();
    169196        this->set = false;
    170 }
     197        LIB_DEBUG_DO(
     198                len = snprintf( text, 256, "Kernel : unregister %p end\n", this );
     199                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
     200        );
     201}
  • src/libcfa/concurrency/coroutine.c

    r70c2df8 r4e6fb8e  
    3232#include "invoke.h"
    3333
    34 extern thread_local processor * this_processor;
     34extern volatile thread_local processor * this_processor;
    3535
    3636//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/invoke.c

    r70c2df8 r4e6fb8e  
    3131extern void __leave_monitor_desc( struct monitor_desc * this );
    3232extern void disable_interrupts();
    33 extern void enable_interrupts();
     33extern void enable_interrupts( const char * );
    3434
    3535void CtxInvokeCoroutine(
     
    6969      struct monitor_desc* mon = &thrd->mon;
    7070      cor->state = Active;
    71       enable_interrupts();
     71      enable_interrupts( __PRETTY_FUNCTION__ );
    7272
    7373      // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this);
  • src/libcfa/concurrency/kernel

    r70c2df8 r4e6fb8e  
    9090        unsigned int preemption;
    9191
    92         unsigned short disable_preempt_count;
     92        bool pending_preemption;
    9393
    94         bool pending_preemption;
     94        char * last_enable;
    9595};
    9696
  • src/libcfa/concurrency/kernel.c

    r70c2df8 r4e6fb8e  
    5959// Global state
    6060
    61 thread_local processor * this_processor;
     61volatile thread_local processor * this_processor;
     62volatile thread_local unsigned short disable_preempt_count;
    6263
    6364coroutine_desc * this_coroutine(void) {
     
    142143        this->preemption_alarm = NULL;
    143144        this->preemption = default_preemption();
    144         this->disable_preempt_count = 1;                //Start with interrupts disabled
    145145        this->pending_preemption = false;
    146146
     
    156156        this->preemption_alarm = NULL;
    157157        this->preemption = default_preemption();
    158         this->disable_preempt_count = 1;
    159158        this->pending_preemption = false;
    160159        this->kernel_thread = pthread_self();
     
    164163        runner{ this };
    165164}
     165
     166LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    166167
    167168void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    171172
    172173        (&this->proc){ cltr, runner };
     174
     175        LIB_DEBUG_DO( assert( validate( &this->alarms ) ) );
    173176}
    174177
     
    212215                        if(readyThread)
    213216                        {
     217                                assert( disable_preempt_count > 0 );
     218
    214219                                runThread(this, readyThread);
     220
     221                                assert( disable_preempt_count > 0 );
    215222
    216223                                //Some actions need to be taken from the kernel
     
    244251        this->current_thread = dst;
    245252
    246         LIB_DEBUG_PRINT_SAFE("Kernel : running %p\n", dst);
    247 
    248253        // Context Switch to the thread
    249254        ThreadCtxSwitch(proc_cor, thrd_cor);
     
    294299        processor * proc = (processor *) arg;
    295300        this_processor = proc;
     301        disable_preempt_count = 1;
    296302        // SKULLDUGGERY: We want to create a context for the processor coroutine
    297303        // which is needed for the 2-step context switch. However, there is no reason
     
    381387void BlockInternal() {
    382388        disable_interrupts();
     389        assert( disable_preempt_count > 0 );
    383390        suspend();
    384         enable_interrupts();
     391        assert( disable_preempt_count > 0 );
     392        enable_interrupts( __PRETTY_FUNCTION__ );
    385393}
    386394
     
    389397        this_processor->finish.action_code = Release;
    390398        this_processor->finish.lock = lock;
     399        assert( disable_preempt_count > 0 );
    391400        suspend();
    392         enable_interrupts();
     401        assert( disable_preempt_count > 0 );
     402        enable_interrupts( __PRETTY_FUNCTION__ );
    393403}
    394404
     
    397407        this_processor->finish.action_code = Schedule;
    398408        this_processor->finish.thrd = thrd;
     409        assert( disable_preempt_count > 0 );
    399410        suspend();
    400         enable_interrupts();
     411        assert( disable_preempt_count > 0 );
     412        enable_interrupts( __PRETTY_FUNCTION__ );
    401413}
    402414
     
    406418        this_processor->finish.lock = lock;
    407419        this_processor->finish.thrd = thrd;
     420        assert( disable_preempt_count > 0 );
    408421        suspend();
    409         enable_interrupts();
     422        assert( disable_preempt_count > 0 );
     423        enable_interrupts( __PRETTY_FUNCTION__ );
    410424}
    411425
     
    415429        this_processor->finish.locks = locks;
    416430        this_processor->finish.lock_count = count;
     431        assert( disable_preempt_count > 0 );
    417432        suspend();
    418         enable_interrupts();
     433        assert( disable_preempt_count > 0 );
     434        enable_interrupts( __PRETTY_FUNCTION__ );
    419435}
    420436
     
    426442        this_processor->finish.thrds = thrds;
    427443        this_processor->finish.thrd_count = thrd_count;
     444        assert( disable_preempt_count > 0 );
    428445        suspend();
    429         enable_interrupts();
     446        assert( disable_preempt_count > 0 );
     447        enable_interrupts( __PRETTY_FUNCTION__ );
    430448}
    431449
     
    466484        this_processor->current_thread = mainThread;
    467485        this_processor->current_coroutine = &mainThread->cor;
     486        disable_preempt_count = 1;
    468487
    469488        // Enable preemption
     
    480499        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
    481500
    482         enable_interrupts();
     501        enable_interrupts( __PRETTY_FUNCTION__ );
    483502}
    484503
    485504void kernel_shutdown(void) {
    486505        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
     506
     507        disable_interrupts();
    487508
    488509        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    600621                append( &this->blocked, this_thread() );
    601622                BlockInternal( &this->lock );
    602                 lock( &this->lock );
    603         }
    604         unlock( &this->lock );
     623        }
     624        else {
     625                unlock( &this->lock );
     626        }
    605627}
    606628
     
    610632                this->cond = true;
    611633
     634                disable_interrupts();
    612635                thread_desc * it;
    613636                while( it = pop_head( &this->blocked) ) {
    614637                        ScheduleThread( it );
    615638                }
     639                enable_interrupts( __PRETTY_FUNCTION__ );
    616640        }
    617641        unlock( &this->lock );
  • src/libcfa/concurrency/kernel_private.h

    r70c2df8 r4e6fb8e  
    5858extern cluster * systemCluster;
    5959extern system_proc_t * systemProcessor;
    60 extern thread_local processor * this_processor;
     60extern volatile thread_local processor * this_processor;
     61extern volatile thread_local unsigned short disable_preempt_count;
    6162
    6263extern "C" {
    6364        void disable_interrupts();
    6465        void enable_interrupts_noRF();
    65         void enable_interrupts();
     66        void enable_interrupts( const char * );
    6667}
    6768
  • src/libcfa/concurrency/preemption.c

    r70c2df8 r4e6fb8e  
    1717#include "preemption.h"
    1818
     19
    1920extern "C" {
    2021#include <errno.h>
     22#define __USE_GNU
    2123#include <signal.h>
     24#undef __USE_GNU
    2225#include <stdio.h>
    2326#include <string.h>
     
    6063        sigprocmask( SIG_BLOCK, &mask, NULL );
    6164        LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");
    62 }
     65
     66        assert( !systemProcessor->alarms.head );
     67        assert( systemProcessor->alarms.tail == &systemProcessor->alarms.head );
     68}
     69
     70LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    6371
    6472void tick_preemption() {
     
    8492                }
    8593
     94                LIB_DEBUG_DO( assert( validate( alarms ) ) );
     95
    8696                if( node->period > 0 ) {
    8797                        node->alarm = currtime + node->period;
     
    98108
    99109        LIB_DEBUG_DO(
     110                assert( validate( alarms ) );
    100111                len = snprintf( text, 256, "Ticking preemption done\n" );
    101112                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
     
    106117        LIB_DEBUG_DO(
    107118                char text[256];
    108                 __attribute__((unused)) int len = snprintf( text, 256, "Processor : updating preemption to %lu\n", duration );
     119                __attribute__((unused)) int len = snprintf( text, 256, "Processor : %p updating preemption to %lu\n", this, duration );
    109120                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    110121        );
     
    139150        this->proc->preemption_alarm = &this->alarm;
    140151        update_preemption( this->proc, this->proc->preemption );
    141 
    142         // enable_interrupts();
    143152}
    144153
     
    155164extern "C" {
    156165        void disable_interrupts() {
    157                 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, 1, __ATOMIC_SEQ_CST );
    158                 assert( prev != (unsigned short) -1 );
     166                __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );
     167                assert( new_val < (unsigned short)65_000 );
     168                assert( new_val != (unsigned short) 0 );
    159169        }
    160170
    161171        void enable_interrupts_noRF() {
    162                 unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     172                unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    163173                assert( prev != (unsigned short) 0 );
    164174        }
    165175
    166         void enable_interrupts() {
    167                 unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );
     176        void enable_interrupts( const char * func ) {
     177                unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    168178                assert( prev != (unsigned short) 0 );
    169179                if( prev == 1 && this_processor->pending_preemption ) {
     
    171181                        LIB_DEBUG_DO(
    172182                                char text[256];
    173                                 __attribute__((unused)) int len = snprintf( text, 256, "Executing deferred CtxSwitch\n" );
     183                                __attribute__((unused)) int len = snprintf( text, 256, "Executing deferred CtxSwitch on %p\n", this_processor );
    174184                                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    175185                        );
    176186                        BlockInternal( this_processor->current_thread );
    177187                }
     188
     189                this_processor->last_enable = func;
    178190        }
    179191}
     
    192204
    193205static inline bool preemption_ready() {
    194         return this_processor->disable_preempt_count == 0;
     206        return disable_preempt_count == 0;
    195207}
    196208
     
    207219        LIB_DEBUG_DO(
    208220                char text[256];
    209                 __attribute__((unused)) int len = snprintf( text, 256, "Ctx Switch IRH\n" );
     221                __attribute__((unused)) int len = snprintf( text, 256, "Ctx Switch IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP]));
    210222                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    211223        );
     
    214226        if( preemption_ready() ) {
    215227                LIB_DEBUG_DO(
    216                         len = snprintf( text, 256, "Ctx Switch IRH : Blocking thread\n" );
     228                        len = snprintf( text, 256, "Ctx Switch IRH : Blocking thread %p on %p\n", this_processor->current_thread, this_processor );
    217229                        LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    218230                );
     
    232244        LIB_DEBUG_DO(
    233245                char text[256];
    234                 __attribute__((unused)) int len = snprintf( text, 256, "\nAlarm IRH\n" );
     246                __attribute__((unused)) int len = snprintf( text, 256, "\nAlarm IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP]) );
    235247                LIB_DEBUG_WRITE( STDERR_FILENO, text, len );
    236248        );
  • src/libcfa/concurrency/thread.c

    r70c2df8 r4e6fb8e  
    2828}
    2929
    30 extern thread_local processor * this_processor;
     30extern volatile thread_local processor * this_processor;
    3131
    3232//-----------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.