Changeset 90c4df0


Ignore:
Timestamp:
Aug 22, 2017, 1:44:12 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
80c72a7
Parents:
e50e9ff
Message:

Implemented search for external scheduling

Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/invoke.h

    re50e9ff r90c4df0  
    2828      #define thread_local _Thread_local
    2929
     30      typedef void (*fptr_t)();
     31
    3032      struct spinlock {
    3133            volatile int lock;
     
    5052            void append( struct __thread_queue_t *, struct thread_desc * );
    5153            struct thread_desc * pop_head( struct __thread_queue_t * );
     54            struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** );
    5255
    5356            void ?{}( struct __condition_stack_t * );
     
    9194            unsigned short acceptable_count;          // number of acceptable functions
    9295            short accepted_index;                     // the index of the accepted function, -1 if none
    93             void (*pre_accept)(void);                 // function to run before an accept
     96            fptr_t pre_accept;                        // function to run before an accept
    9497       };
    9598
    9699      struct thread_desc {
     100            // Core threading fields
    97101            struct coroutine_desc cor;                // coroutine body used to store context
    98102            struct monitor_desc mon;                  // monitor body used for mutual exclusion
     103
     104            // Link lists fields
    99105            struct thread_desc * next;                // instrusive link field for threads
     106
     107            // Current status related to monitors
    100108            struct monitor_desc ** current_monitors;  // currently held monitors
    101109            unsigned short current_monitor_count;     // number of currently held monitors
     110            fptr_t current_monitor_func;              // last function that acquired monitors
    102111     };
    103112
  • src/libcfa/concurrency/kernel.c

    re50e9ff r90c4df0  
    668668}
    669669
     670thread_desc * remove( __thread_queue_t * this, thread_desc ** it ) {
     671        thread_desc * thrd = *it;
     672        verify( thrd );
     673
     674        (*it) = thrd->next;
     675
     676        if( this->tail == &thrd->next ) {
     677                this->tail = it;
     678        }
     679
     680        thrd->next = NULL;
     681
     682        verify( (this->head == NULL) == (&this->head == this->tail) );
     683        verify( *this->tail == NULL );
     684        return thrd;
     685}
     686
     687
     688
    670689void ?{}( __condition_stack_t * this ) {
    671690        this->top = NULL;
  • src/libcfa/concurrency/monitor

    re50e9ff r90c4df0  
    3939        monitor_desc ** prev_mntrs;
    4040        unsigned short  prev_count;
     41        fptr_t          prev_func;
    4142};
    4243
     
    99100// External scheduling
    100101
    101 typedef void (*void_fptr_t)(void);
    102 
    103102struct __acceptable_t {
    104         void_fptr_t func;
     103        fptr_t func;
    105104        unsigned short count;
    106105        monitor_desc ** monitors;
  • src/libcfa/concurrency/monitor.c

    re50e9ff r90c4df0  
    7373                thread_desc * thrd = this_thread;
    7474
     75                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     76
    7577                this->accepted_index = -1;
    7678                if( !this->owner ) {
    7779                        // No one has the monitor, just take it
    7880                        set_owner( this, thrd );
     81
     82                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon is free \n");
    7983                }
    8084                else if( this->owner == thrd) {
     
    8286                        verify( this->recursion > 0 );
    8387                        this->recursion += 1;
     88
     89                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
    8490                }
    8591                else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) {
    8692                        // Some one was waiting for us, enter
    8793                        set_owner( this, thrd );
     94
     95                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts \n");
    8896                }
    8997                else {
     98                        LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
     99
    90100                        // Some one else has the monitor, wait in line for it
    91101                        append( &this->entry_queue, thrd );
    92102                        BlockInternal( &this->lock );
    93103
     104                        LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
     105
    94106                        // BlockInternal will unlock spinlock, no need to unlock ourselves
    95107                        return;
    96108                }
     109
     110                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
    97111
    98112                // Release the lock and leave
     
    194208        qsort(this->m, count);
    195209
    196         // Enter the monitors in order
    197         enter( this->m, this->count, func );
    198 
    199210        // Save previous thread context
    200211        this->prev_mntrs = this_thread->current_monitors;
    201212        this->prev_count = this_thread->current_monitor_count;
     213        this->prev_func  = this_thread->current_monitor_func;
    202214
    203215        // Update thread context (needed for conditions)
    204216        this_thread->current_monitors      = m;
    205217        this_thread->current_monitor_count = count;
     218        this_thread->current_monitor_func  = func;
     219
     220        // Enter the monitors in order
     221        enter( this->m, this->count, func );
    206222}
    207223
     
    214230        this_thread->current_monitors      = this->prev_mntrs;
    215231        this_thread->current_monitor_count = this->prev_count;
     232        this_thread->current_monitor_func  = this->prev_func;
    216233}
    217234
     
    402419        thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count );
    403420
     421        LIB_DEBUG_PRINT_SAFE("Owner(s) :");
     422        for(int i = 0; i < count; i++) {
     423                LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner );
     424        }
     425        LIB_DEBUG_PRINT_SAFE("\n");
     426
     427        LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next);
     428
    404429        if( !next ) {
    405430                // Update acceptables on the current monitors
     
    409434                }
    410435        }
     436        else {
     437                for(int i = 0; i < count; i++) {
     438                        set_owner( monitors[i], next );
     439                }
     440        }
     441
    411442
    412443        save_recursion( monitors, recursions, count );
     444
    413445
    414446        // Everything is ready to go to sleep
     
    602634}
    603635
     636static inline bool match( __acceptable_t * acc, thread_desc * thrd ) {
     637        verify( thrd );
     638        verify( acc );
     639        if( acc->func != thrd->current_monitor_func ) return false;
     640
     641        return true;
     642}
     643
    604644static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
     645
     646        __thread_queue_t * entry_queue = &monitors[0]->entry_queue;
     647
     648        // For each thread in the entry-queue
     649        for(    thread_desc ** thrd_it = &entry_queue->head;
     650                *thrd_it;
     651                thrd_it = &(*thrd_it)->next)
     652        {
     653                // For each acceptable check if it matches
     654                __acceptable_t * acc_end = acceptables + acc_count;
     655                for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) {
     656                        // Check if we have a match
     657                        if( match( acc_it, *thrd_it ) ) {
     658
     659                                // If we have a match return it
     660                                // after removeing it from the entry queue
     661                                return remove( entry_queue, thrd_it );
     662                        }
     663                }
     664        }
     665
    605666        return NULL;
    606667}
  • src/libcfa/concurrency/preemption.c

    re50e9ff r90c4df0  
    332332                assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int);
    333333
    334                 LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
     334                // LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
    335335                // Switch on the code (a.k.a. the sender) to
    336336                switch( info.si_code )
     
    340340                case SI_TIMER:
    341341                case SI_KERNEL:
    342                         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
     342                        // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
    343343                        lock( &event_kernel->lock DEBUG_CTX2 );
    344344                        tick_preemption();
  • src/tests/sched-ext.c

    re50e9ff r90c4df0  
    77#include <time.h>
    88
    9 static const unsigned long N = 2_500ul;
     9static const unsigned long N = 500ul;
    1010
    1111#ifndef PREEMPTION_RATE
     
    2424thread Acceptee {};
    2525
     26volatile bool done;
     27
     28unsigned rand10() {
     29        return (unsigned)rand48() % 10;
     30}
     31
    2632//----------------------------------------------------------------------------------------------------
    2733// Acceptor
     
    2935
    3036void do_wait( global_t * mutex a ) {
    31         sout | "Preparing to wait" | endl;
     37        sout | "Waiting to accept" | endl;
     38        yield( rand10() );
     39
     40        sout | "Accepting" | endl;
    3241
    3342        __acceptable_t acceptable;
    34         acceptable.func          = (void_fptr_t)do_notify;
     43        acceptable.func          = (fptr_t)do_notify;
    3544        acceptable.count         = 1;
    3645        acceptable.monitors      = &a;
    3746        acceptable.run_preaccept = false;
    3847
    39         sout | "Waiting for notify" | endl;
     48        __accept_internal( 1, &acceptable );
    4049
    41         int ret = __accept_internal( 1, &acceptable );
    42         sout | "Back from wating, accepted" | ret | endl;
     50        sout | "Accepted" | endl;
     51        yield( rand10() );
    4352}
    4453
    4554void main( Acceptor* this ) {
    46         do_wait( &globalA );
     55        for( int i = 0; i < N; i++ ) {
     56                do_wait( &globalA );
     57                sout | i | endl;
     58        }
     59
     60        done = true;
    4761}
    4862
     
    5064// Acceptee
    5165void do_notify( global_t * mutex a ) {
    52         sout | "Notifying" | endl;
     66
    5367}
    5468
    5569void main( Acceptee* this ) {
    56         for( volatile int i = 0; i < N; i++ );
    57 
    58         sout | "Call Notify" | endl;
    59         do_notify( &globalA );
     70        while( !done ) {
     71                yield( rand10() );
     72                do_notify( &globalA );
     73                yield( rand10() );
     74        }
    6075}
    6176
     
    6378// Main
    6479int main(int argc, char* argv[]) {
    65         processor p;
     80        done = false;
     81        rand48seed( time( NULL ) );
     82        printf("%p\n", &globalA);
    6683        sout | "Starting" | endl;
    6784        {
    6885                Acceptor r;
    69                 Acceptee e;
     86                Acceptee e[13];
     87
    7088        }
    7189        sout | "Done" | endl;
Note: See TracChangeset for help on using the changeset viewer.