Changeset 6ae8c92 for src/libcfa/concurrency
- Timestamp:
- Sep 20, 2017, 4:50:52 PM (7 years ago)
- 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
- Location:
- src/libcfa/concurrency
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.h
r0895cba r6ae8c92 84 84 }; 85 85 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 86 92 struct monitor_desc { 87 93 struct spinlock lock; // spinlock to protect internal data … … 90 96 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 91 97 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 96 99 }; 97 100 98 struct __monitor_group {101 struct __monitor_group_t { 99 102 struct monitor_desc ** list; // currently held monitors 100 103 short size; // number of currently held monitors … … 107 110 struct monitor_desc self_mon; // monitor body used for mutual exclusion 108 111 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 thread112 struct __monitor_group_t monitors; // monitors currently held by this thread 110 113 111 114 // Link lists fields … … 117 120 #ifdef __CFORALL__ 118 121 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 ) { 120 123 return this.list[index]; 121 124 } 122 125 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 ) { 124 127 if( lhs.size != rhs.size ) return false; 125 128 if( lhs.func != rhs.func ) return false; -
src/libcfa/concurrency/monitor
r0895cba r6ae8c92 33 33 (this.signal_stack){}; 34 34 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; 38 38 } 39 39 … … 105 105 106 106 struct __acceptable_t { 107 __monitor_group monitors;107 __monitor_group_t monitors; 108 108 bool is_dtor; 109 109 }; 110 110 111 int __waitfor_internal( unsigned short count, __acceptable_t * acceptables, int duration );111 void __waitfor_internal( const __waitfor_mask_t & mask, int duration ); 112 112 113 113 // Local Variables: // -
src/libcfa/concurrency/monitor.c
r0895cba r6ae8c92 25 25 static inline void set_owner( monitor_desc * this, thread_desc * owner ); 26 26 static inline thread_desc * next_thread( monitor_desc * this ); 27 static inline int is_accepted( thread_desc * owner, monitor_desc * this, const __monitor_group& monitors );27 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors ); 28 28 29 29 static inline void lock_all( spinlock ** locks, unsigned short count ); … … 42 42 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ); 43 43 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);44 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count ); 45 46 static inline short count_max( const __waitfor_mask_t & mask ); 47 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ); 48 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 49 49 50 50 //----------------------------------------------------------------------------- … … 72 72 extern "C" { 73 73 // Enter single monitor 74 static void __enter_monitor_desc( const __monitor_group & group ) {74 static void __enter_monitor_desc( const __monitor_group_t & group ) { 75 75 monitor_desc * this = group.list[0]; 76 76 … … 81 81 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); 82 82 83 this->accepted_index = -1;84 83 if( !this->owner ) { 85 84 // No one has the monitor, just take it … … 95 94 LIB_DEBUG_PRINT_SAFE("Kernel : mon already owned \n"); 96 95 } 97 else if( (this->accepted_index = is_accepted( thrd, this, group)) >= 0) {96 else if( is_accepted( this, group) ) { 98 97 // Some one was waiting for us, enter 99 98 set_owner( this, thrd ); … … 184 183 // Enter multiple monitor 185 184 // relies on the monitor array being sorted 186 static inline void enter( __monitor_group monitors ) {185 static inline void enter( __monitor_group_t monitors ) { 187 186 for(int i = 0; i < monitors.size; i++) { 188 187 __enter_monitor_desc( monitors ); … … 219 218 220 219 // Enter the monitors in order 221 __monitor_group group = {this.m, this.count, func};220 __monitor_group_t group = {this.m, this.count, func}; 222 221 enter( group ); 223 222 } … … 417 416 // setup mask 418 417 // block 419 int __waitfor_internal( unsigned short acc_count, __acceptable_t * acceptables, int duration ) {418 void __waitfor_internal( const __waitfor_mask_t & mask, int duration ) { 420 419 // This statment doesn't have a contiguous list of monitors... 421 420 // Create one! 422 short max = count_max( acc_count, acceptables);421 short max = count_max( mask ); 423 422 monitor_desc * mon_storage[max]; 424 short actual_count = aggregate( mon_storage, acc_count, acceptables);423 short actual_count = aggregate( mon_storage, mask ); 425 424 426 425 // Create storage for monitor context … … 432 431 { 433 432 // 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 ); 437 435 438 436 if( next ) { 439 if( acceptables[index].is_dtor ) {437 if( mask.clauses[index].is_dtor ) { 440 438 #warning case not implemented 441 439 } … … 463 461 if( duration == 0 ) return -1; 464 462 465 set_mask( monitors, count, acceptables, acc_count );466 463 467 464 verifyf( duration < 0, "Timeout on waitfor statments not supported yet."); … … 469 466 470 467 save_recursion( monitors, recursions, count ); 468 set_mask( monitors, count, mask ); 471 469 472 470 … … 481 479 lock_all( locks, count ); 482 480 restore_recursion( monitors, recursions, count ); 483 int acc_idx = monitors[0]->accepted_index;484 481 unlock_all( locks, count ); 485 482 486 return acc_idx;483 return mask.accepted; 487 484 } 488 485 … … 625 622 } 626 623 627 static inline int is_accepted( thread_desc * owner, monitor_desc * this, const __monitor_group& group ) {628 __acceptable_t * accs = this->acceptables; // Optim629 int acc_cnt = this->acceptable_count;624 static 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; 630 627 631 628 // Check if there are any acceptable functions 632 if( ! accs) return -1;629 if( !it ) return -1; 633 630 634 631 // 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; 636 633 637 634 // 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 } 642 640 } 643 641 644 642 // 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 646 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) { 649 647 650 648 __thread_queue_t * entry_queue = &monitors[0]->entry_queue; … … 657 655 // For each acceptable check if it matches 658 656 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++ ) { 661 659 // Check if we have a match 662 if( acc_it->monitors == (*thrd_it)->monitors ) {660 if( it->monitors == (*thrd_it)->monitors ) { 663 661 664 662 // If we have a match return it … … 672 670 } 673 671 674 static inline short count_max( short acc_count, __acceptable_t * acceptables) {672 static inline short count_max( const __waitfor_mask_t & mask ) { 675 673 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; 678 676 } 679 677 return max; 680 678 } 681 679 682 static inline short aggregate( monitor_desc ** storage, short count, __acceptable_t * acceptables) {680 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) { 683 681 #warning function not implemented 684 682 return 0; 685 683 } 686 684 687 static inline void set_mask( monitor_desc ** storage, short count, __acceptable_t * acceptables, short acc_count) {685 static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) { 688 686 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; 692 688 } 693 689 }
Note: See TracChangeset
for help on using the changeset viewer.