Changeset 44264c5


Ignore:
Timestamp:
May 23, 2017, 12:17:07 PM (8 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:
2c9ebab
Parents:
535adab
Message:

Working implementation of internal scheduling, TODO some cleanup

Location:
src/libcfa/concurrency
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/monitor

    r535adab r44264c5  
    8787void wait( condition * this );
    8888void signal( condition * this );
     89void signal_block( condition * this );
    8990#endif //MONITOR_H
  • src/libcfa/concurrency/monitor.c

    r535adab r44264c5  
    6262                        //Some one else has the monitor, wait in line for it
    6363                        append( &this->entry_queue, thrd );
     64                        LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    6465                        ScheduleInternal( &this->lock );
    6566
     
    9798                unlock( &this->lock );
    9899
     100                LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
     101
    99102                //We need to wake-up the thread
    100103                ScheduleThread( new_owner );
     
    149152        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    150153        assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
     154        assertf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
    151155
    152156        unsigned short count = this->monitor_count;
     
    184188        }
    185189
    186         debug_break();
    187 
    188190        for( int i = 0; i < count; i++) {
    189191                thread_desc * new_owner = next_thread( this->monitors[i] );
     
    191193        }
    192194
    193         debug_break();
    194 
    195195        LIB_DEBUG_PRINT_SAFE("Will unblock: ");
    196196        for(int i = 0; i < thread_count; i++) {
     
    202202        ScheduleInternal( locks, count, threads, thread_count );
    203203
    204 
     204        debug_break();
    205205        //WE WOKE UP
    206206
     
    224224        unsigned short count = this->monitor_count;
    225225       
     226        //Some more checking in debug
    226227        LIB_DEBUG_DO(
    227228                thread_desc * this_thrd = this_thread();
     
    237238        );
    238239
     240        //Lock all the monitors
    239241        lock_all( this->monitors, NULL, count );
    240242        LIB_DEBUG_PRINT_SAFE("Signalling");
    241243
     244        //Pop the head of the waiting queue
    242245        __condition_node_t * node = pop_head( &this->blocked );
     246
     247        //Add the thread to the proper AS stack
    243248        for(int i = 0; i < count; i++) {
    244249                __condition_criterion_t * crit = &node->criteria[i];
     
    250255        LIB_DEBUG_PRINT_SAFE("\n");
    251256
     257        //Release
    252258        unlock_all( this->monitors, count );
     259}
     260
     261void signal_block( condition * this ) {
     262        if( !this->blocked.head ) {
     263                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     264                return;
     265        }
     266
     267        //Check that everything is as expected
     268        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
     269        assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
     270
     271        unsigned short count = this->monitor_count;
     272        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
     273        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
     274
     275        lock_all( this->monitors, locks, count );
     276
     277        //create creteria
     278        __condition_node_t waiter;
     279        waiter.waiting_thread = this_thread();
     280        waiter.count = count;
     281        waiter.next = NULL;
     282
     283        __condition_criterion_t criteria[count];
     284        for(int i = 0; i < count; i++) {
     285                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     286                criteria[i].ready  = false;
     287                criteria[i].owner  = &waiter;
     288                criteria[i].next   = NULL;
     289                criteria[i].target = this->monitors[i];
     290                push( &criteria[i].target->signal_stack, &criteria[i] );
     291        }
     292
     293        waiter.criteria = criteria;
     294
     295        //save contexts
     296        save_recursion( this->monitors, recursions, count );
     297
     298        //Find the thread to run
     299        thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
     300        for(int i = 0; i < count; i++) {
     301                set_owner( this->monitors[i], signallee );
     302        }
     303
     304        LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" );
     305        debug_break();
     306
     307        //Everything is ready to go to sleep
     308        ScheduleInternal( locks, count, &signallee, 1 );
     309
     310        debug_break();
     311        LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
     312
     313        //We are back, restore the owners and recursions
     314        lock_all( locks, count );
     315        restore_recursion( this->monitors, recursions, count );
     316        unlock_all( locks, count );
    253317}
    254318
     
    335399
    336400        for(    int i = 0; i < count; i++ ) {
     401
    337402                LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
    338403                if( &criteria[i] == target ) {
  • src/libcfa/concurrency/thread

    r535adab r44264c5  
    8282
    8383void yield();
     84void yield( unsigned times );
    8485
    8586#endif //THREADS_H
  • src/libcfa/concurrency/thread.c

    r535adab r44264c5  
    8787}
    8888
     89void yield( unsigned times ) {
     90        for( unsigned i = 0; i < times; i++ ) {
     91                yield();
     92        }
     93}
     94
    8995void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    9096        // set state of current coroutine to inactive
Note: See TracChangeset for help on using the changeset viewer.