Ignore:
Timestamp:
Sep 20, 2017, 4:50:52 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:
a2dbad10
Parents:
0895cba
Message:

Changed lib-side waitfor to use a mask type instead of a pointer and an int. The accepted index is now in the mask type, everything else points to it

Location:
src/libcfa/concurrency
Files:
3 edited

Legend:

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

    r0895cba r6ae8c92  
    8484      };
    8585
     86      struct __waitfor_mask_t {
     87            short * accepted;                         // the index of the accepted function, -1 if none
     88            struct __acceptable_t * clauses;          // list of acceptable functions, null if any
     89            short size;                               // number of acceptable functions
     90      };
     91
    8692      struct monitor_desc {
    8793            struct spinlock lock;                     // spinlock to protect internal data
     
    9096            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    9197            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    92 
    93             struct __acceptable_t * acceptables;      // list of acceptable functions, null if any
    94             unsigned short acceptable_count;          // number of acceptable functions
    95             short accepted_index;                     // the index of the accepted function, -1 if none
     98            struct __waitfor_mask_t mask;               // mask used to know if some thread is waiting for something while holding the monitor
    9699      };
    97100
    98       struct __monitor_group {
     101      struct __monitor_group_t {
    99102            struct monitor_desc ** list;              // currently held monitors
    100103            short                  size;              // number of currently held monitors
     
    107110            struct monitor_desc    self_mon;          // monitor body used for mutual exclusion
    108111            struct monitor_desc *  self_mon_p;        // pointer to monitor with sufficient lifetime for current monitors
    109             struct __monitor_group monitors;          // monitors currently held by this thread
     112            struct __monitor_group_t monitors;          // monitors currently held by this thread
    110113
    111114            // Link lists fields
     
    117120     #ifdef __CFORALL__
    118121     extern "Cforall" {
    119             static inline monitor_desc * ?[?]( const __monitor_group & this, ptrdiff_t index ) {
     122            static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
    120123                  return this.list[index];
    121124            }
    122125
    123             static inline bool ?==?( const __monitor_group & lhs, const __monitor_group & rhs ) {
     126            static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
    124127                  if( lhs.size != rhs.size ) return false;
    125128                  if( lhs.func != rhs.func ) return false;
  • src/libcfa/concurrency/monitor

    r0895cba r6ae8c92  
    3333        (this.signal_stack){};
    3434        this.recursion = 0;
    35         this.acceptables = NULL;
    36         this.acceptable_count = 0;
    37         this.accepted_index = -1;
     35        this.mask.accepted = NULL;
     36        this.mask.clauses  = NULL;
     37        this.mask.size     = 0;
    3838}
    3939
     
    105105
    106106struct __acceptable_t {
    107         __monitor_group monitors;
     107        __monitor_group_t monitors;
    108108        bool is_dtor;
    109109};
    110110
    111 int __waitfor_internal( unsigned short count, __acceptable_t * acceptables, int duration );
     111void __waitfor_internal( const __waitfor_mask_t & mask, int duration );
    112112
    113113// Local Variables: //
  • src/libcfa/concurrency/monitor.c

    r0895cba r6ae8c92  
    2525static inline void set_owner( monitor_desc * this, thread_desc * owner );
    2626static inline thread_desc * next_thread( monitor_desc * this );
    27 static inline int is_accepted( thread_desc * owner, monitor_desc * this, const __monitor_group & monitors );
     27static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors );
    2828
    2929static inline void lock_all( spinlock ** locks, unsigned short count );
     
    4242static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
    4343
    44 static inline [thread_desc *, int] search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );
    45 
    46 static inline short count_max( short acc_count, __acceptable_t * acceptables );
    47 static inline short aggregate( monitor_desc ** storage, short count, __acceptable_t * acceptables );
    48 static inline void  set_mask ( monitor_desc ** storage, short count, __acceptable_t * acceptables, short acc_count );
     44static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count );
     45
     46static inline short count_max( const __waitfor_mask_t & mask );
     47static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask );
     48static inline void  set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask );
    4949
    5050//-----------------------------------------------------------------------------
     
    7272extern "C" {
    7373        // Enter single monitor
    74         static void __enter_monitor_desc( const __monitor_group & group ) {
     74        static void __enter_monitor_desc( const __monitor_group_t & group ) {
    7575                monitor_desc * this = group.list[0];
    7676
     
    8181                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    8282
    83                 this->accepted_index = -1;
    8483                if( !this->owner ) {
    8584                        // No one has the monitor, just take it
     
    9594                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
    9695                }
    97                 else if( (this->accepted_index = is_accepted( thrd, this, group)) >= 0 ) {
     96                else if( is_accepted( this, group) ) {
    9897                        // Some one was waiting for us, enter
    9998                        set_owner( this, thrd );
     
    184183// Enter multiple monitor
    185184// relies on the monitor array being sorted
    186 static inline void enter( __monitor_group monitors ) {
     185static inline void enter( __monitor_group_t monitors ) {
    187186        for(int i = 0; i < monitors.size; i++) {
    188187                __enter_monitor_desc( monitors );
     
    219218
    220219        // Enter the monitors in order
    221         __monitor_group group = {this.m, this.count, func};
     220        __monitor_group_t group = {this.m, this.count, func};
    222221        enter( group );
    223222}
     
    417416//              setup mask
    418417//              block
    419 int __waitfor_internal( unsigned short acc_count, __acceptable_t * acceptables, int duration ) {
     418void __waitfor_internal( const __waitfor_mask_t & mask, int duration ) {
    420419        // This statment doesn't have a contiguous list of monitors...
    421420        // Create one!
    422         short max = count_max( acc_count, acceptables );
     421        short max = count_max( mask );
    423422        monitor_desc * mon_storage[max];
    424         short actual_count = aggregate( mon_storage, acc_count, acceptables );
     423        short actual_count = aggregate( mon_storage, mask );
    425424
    426425        // Create storage for monitor context
     
    432431        {
    433432                // Check if the entry queue
    434                 thread_desc * next;
    435                 int index;
    436                 [next, index] = search_entry_queue( acceptables, acc_count, monitors, count );
     433                thread_desc * next; int index;
     434                [next, index] = search_entry_queue( mask, monitors, count );
    437435
    438436                if( next ) {
    439                         if( acceptables[index].is_dtor ) {
     437                        if( mask.clauses[index].is_dtor ) {
    440438                                #warning case not implemented
    441439                        }
     
    463461        if( duration == 0 ) return -1;
    464462
    465         set_mask( monitors, count, acceptables, acc_count );
    466463
    467464        verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");
     
    469466
    470467        save_recursion( monitors, recursions, count );
     468        set_mask( monitors, count, mask );
    471469
    472470
     
    481479        lock_all( locks, count );
    482480        restore_recursion( monitors, recursions, count );
    483         int acc_idx = monitors[0]->accepted_index;
    484481        unlock_all( locks, count );
    485482
    486         return acc_idx;
     483        return mask.accepted;
    487484}
    488485
     
    625622}
    626623
    627 static inline int is_accepted( thread_desc * owner, monitor_desc * this, const __monitor_group & group ) {
    628         __acceptable_t* accs = this->acceptables; // Optim
    629         int acc_cnt = this->acceptable_count;
     624static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
     625        __acceptable_t * it = this->mask.clauses; // Optim
     626        int count = this->mask.size;
    630627
    631628        // Check if there are any acceptable functions
    632         if( !accs ) return -1;
     629        if( !it ) return -1;
    633630
    634631        // If this isn't the first monitor to test this, there is no reason to repeat the test.
    635         if( this != group[0] ) return group[0]->accepted_index;
     632        if( this != group[0] ) return group[0]->mask.accepted >= 0;
    636633
    637634        // For all acceptable functions check if this is the current function.
    638         for( int i = 0; i < acc_cnt; i++ ) {
    639                 __acceptable_t * acc = &accs[i];
    640 
    641                 if( acc->monitors == group ) return i;
     635        for( short i = 0; i < count; i++, it++ ) {
     636                if( it->monitors == group ) {
     637                        *this->mask.accepted = i;
     638                        return true;
     639                }
    642640        }
    643641
    644642        // No function matched
    645         return -1;
    646 }
    647 
    648 static inline [thread_desc *, int] search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
     643        return false;
     644}
     645
     646static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) {
    649647
    650648        __thread_queue_t * entry_queue = &monitors[0]->entry_queue;
     
    657655                // For each acceptable check if it matches
    658656                int i;
    659                 __acceptable_t * acc_end = acceptables + acc_count;
    660                 for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++, i++ ) {
     657                __acceptable_t * end = mask.clauses + mask.size;
     658                for( __acceptable_t * it = mask.clauses; it != end; it++, i++ ) {
    661659                        // Check if we have a match
    662                         if( acc_it->monitors == (*thrd_it)->monitors ) {
     660                        if( it->monitors == (*thrd_it)->monitors ) {
    663661
    664662                                // If we have a match return it
     
    672670}
    673671
    674 static inline short count_max( short acc_count, __acceptable_t * acceptables ) {
     672static inline short count_max( const __waitfor_mask_t & mask ) {
    675673        short max = 0;
    676         for( int i = 0; i < acc_count; i++ ) {
    677                 max += acceptables[i].monitors.size;
     674        for( int i = 0; i < mask.size; i++ ) {
     675                max += mask.clauses[i].monitors.size;
    678676        }
    679677        return max;
    680678}
    681679
    682 static inline short aggregate( monitor_desc ** storage, short count, __acceptable_t * acceptables ) {
     680static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {
    683681        #warning function not implemented
    684682        return 0;
    685683}
    686684
    687 static inline void set_mask( monitor_desc ** storage, short count, __acceptable_t * acceptables, short acc_count ) {
     685static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {
    688686        for(int i = 0; i < count; i++) {
    689                 storage[i]->acceptables      = acceptables;
    690                 storage[i]->acceptable_count = acc_count;
    691                 storage[i]->accepted_index   = -1;
     687                storage[i]->mask = mask;
    692688        }
    693689}
Note: See TracChangeset for help on using the changeset viewer.