Changeset 52fad0c
- Timestamp:
- Aug 27, 2021, 3:52:13 PM (22 months ago)
- Branches:
- ADT, enum, forall-pointer-decay, jacob/cs343-translation, master, pthread-emulation, qualifiedEnum
- Children:
- 1d402be
- Parents:
- 6c2dc00 (diff), 702839bb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/monitor.cfa
r6c2dc00 r52fad0c 990 990 } 991 991 992 //----------------------------------------------------------------------------- 993 // Enter routine for mutex stmt 994 // Can't be accepted since a mutex stmt is effectively an anonymous routine 995 // Thus we do not need a monitor group 996 void lock( monitor$ * this ) { 997 thread$ * thrd = active_thread(); 998 999 // Lock the monitor spinlock 1000 lock( this->lock __cfaabi_dbg_ctx2 ); 1001 1002 __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); 1003 1004 if( unlikely(0 != (0x1 & (uintptr_t)this->owner)) ) { 1005 abort( "Attempt by thread \"%.256s\" (%p) to access joined monitor %p.", thrd->self_cor.name, thrd, this ); 1006 } 1007 else if( !this->owner ) { 1008 // No one has the monitor, just take it 1009 __set_owner( this, thrd ); 1010 1011 __cfaabi_dbg_print_safe( "Kernel : mon is free \n" ); 1012 } 1013 else if( this->owner == thrd) { 1014 // We already have the monitor, just note how many times we took it 1015 this->recursion += 1; 1016 1017 __cfaabi_dbg_print_safe( "Kernel : mon already owned \n" ); 1018 } 1019 else { 1020 __cfaabi_dbg_print_safe( "Kernel : blocking \n" ); 1021 1022 // Some one else has the monitor, wait in line for it 1023 /* paranoid */ verify( thrd->link.next == 0p ); 1024 append( this->entry_queue, thrd ); 1025 /* paranoid */ verify( thrd->link.next == 1p ); 1026 1027 unlock( this->lock ); 1028 park(); 1029 1030 __cfaabi_dbg_print_safe( "Kernel : %10p Entered mon %p\n", thrd, this); 1031 1032 /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this ); 1033 return; 1034 } 1035 1036 __cfaabi_dbg_print_safe( "Kernel : %10p Entered mon %p\n", thrd, this); 1037 1038 /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this ); 1039 /* paranoid */ verify( this->lock.lock ); 1040 1041 // Release the lock and leave 1042 unlock( this->lock ); 1043 return; 1044 } 1045 1046 // Leave routine for mutex stmt 1047 // Is just a wrapper around __leave for the is_lock trait to see 1048 void unlock( monitor$ * this ) { __leave( this ); } 1049 992 1050 // Local Variables: // 993 1051 // mode: c // -
libcfa/src/concurrency/monitor.hfa
r6c2dc00 r52fad0c 149 149 void __waitfor_internal( const __waitfor_mask_t & mask, int duration ); 150 150 151 // lock and unlock routines for mutex statements to use 152 void lock( monitor$ * this ); 153 void unlock( monitor$ * this ); 154 151 155 // Local Variables: // 152 156 // mode: c // -
src/Concurrency/Keywords.cc
r6c2dc00 r52fad0c 93 93 ObjectDecl * addField( StructDecl * ); 94 94 void addRoutines( ObjectDecl *, FunctionDecl * ); 95 void addLockUnlockRoutines( StructDecl * ); 95 96 96 97 virtual bool is_target( StructDecl * decl ) = 0; … … 322 323 StructDecl* dtor_guard_decl = nullptr; 323 324 StructDecl* thread_guard_decl = nullptr; 325 StructDecl* lock_guard_decl = nullptr; 324 326 325 327 static std::unique_ptr< Type > generic_func; … … 463 465 } 464 466 465 466 467 void ConcurrentSueKeyword::handle( StructDecl * decl ) { 467 468 if( ! decl->body ) return; … … 479 480 FunctionDecl * func = forwardDeclare( decl ); 480 481 ObjectDecl * field = addField( decl ); 482 483 // add get_.* routine 481 484 addRoutines( field, func ); 485 // add lock/unlock routines to monitors for use by mutex stmt 486 addLockUnlockRoutines( decl ); 482 487 } 483 488 … … 612 617 } 613 618 619 // This function adds the get_.* routine body for coroutines, monitors etc 620 // after their corresponding struct has been made 614 621 void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) { 615 622 CompoundStmt * statement = new CompoundStmt(); … … 634 641 635 642 declsToAddAfter.push_back( get_decl ); 643 } 644 645 // Generates lock/unlock routines for monitors to be used by mutex stmts 646 void ConcurrentSueKeyword::addLockUnlockRoutines( StructDecl * decl ) { 647 // this routine will be called for all ConcurrentSueKeyword children so only continue if we are a monitor 648 if ( !decl->is_monitor() ) return; 649 650 FunctionType * lock_fn_type = new FunctionType( noQualifiers, false ); 651 FunctionType * unlock_fn_type = new FunctionType( noQualifiers, false ); 652 653 // create this ptr parameter for both routines 654 ObjectDecl * this_decl = new ObjectDecl( 655 "this", 656 noStorageClasses, 657 LinkageSpec::Cforall, 658 nullptr, 659 new ReferenceType( 660 noQualifiers, 661 new StructInstType( 662 noQualifiers, 663 decl 664 ) 665 ), 666 nullptr 667 ); 668 669 lock_fn_type->get_parameters().push_back( this_decl->clone() ); 670 unlock_fn_type->get_parameters().push_back( this_decl->clone() ); 671 672 delete this_decl; 673 674 675 ////////////////////////////////////////////////////////////////////// 676 // The following generates this lock routine for all monitors 677 /* 678 void lock (monitor_t & this) { 679 lock(get_monitor(this)); 680 } 681 */ 682 FunctionDecl * lock_decl = new FunctionDecl( 683 "lock", 684 Type::Static, 685 LinkageSpec::Cforall, 686 lock_fn_type, 687 nullptr, 688 { }, 689 Type::Inline 690 ); 691 fixupGenerics(lock_fn_type, decl); 692 693 UntypedExpr * get_monitor_lock = new UntypedExpr ( 694 new NameExpr( "get_monitor" ), 695 { new VariableExpr( lock_fn_type->get_parameters().front() ) } 696 ); 697 698 CompoundStmt * lock_statement = new CompoundStmt(); 699 lock_statement->push_back( 700 new ExprStmt( 701 new UntypedExpr ( 702 new NameExpr( "lock" ), 703 { 704 get_monitor_lock 705 } 706 ) 707 ) 708 ); 709 lock_decl->set_statements( lock_statement ); 710 711 ////////////////////////////////////////////////////////////////// 712 // The following generates this routine for all monitors 713 /* 714 void unlock (monitor_t & this) { 715 unlock(get_monitor(this)); 716 } 717 */ 718 FunctionDecl * unlock_decl = new FunctionDecl( 719 "unlock", 720 Type::Static, 721 LinkageSpec::Cforall, 722 unlock_fn_type, 723 nullptr, 724 { }, 725 Type::Inline 726 ); 727 fixupGenerics(unlock_fn_type, decl); 728 729 CompoundStmt * unlock_statement = new CompoundStmt(); 730 731 UntypedExpr * get_monitor_unlock = new UntypedExpr ( 732 new NameExpr( "get_monitor" ), 733 { new VariableExpr( unlock_fn_type->get_parameters().front() ) } 734 ); 735 736 unlock_statement->push_back( 737 new ExprStmt( 738 new UntypedExpr( 739 new NameExpr( "unlock" ), 740 { 741 get_monitor_unlock 742 } 743 ) 744 ) 745 ); 746 unlock_decl->set_statements( unlock_statement ); 747 748 // pushes routines to declsToAddAfter to add at a later time 749 declsToAddAfter.push_back( lock_decl ); 750 declsToAddAfter.push_back( unlock_decl ); 636 751 } 637 752 … … 937 1052 assert( !thread_guard_decl ); 938 1053 thread_guard_decl = decl; 1054 } 1055 else if ( decl->name == "__mutex_stmt_lock_guard" && decl->body ) { 1056 assert( !lock_guard_decl ); 1057 lock_guard_decl = decl; 939 1058 } 940 1059 } … … 1081 1200 new PointerType( 1082 1201 noQualifiers, 1083 new StructInstType( 1084 noQualifiers, 1085 monitor_decl 1086 ) 1202 new TypeofType( noQualifiers, args.front()->clone() ) 1087 1203 ), 1088 1204 new ConstantExpr( Constant::from_ulong( args.size() ) ), … … 1093 1209 map_range < std::list<Initializer*> > ( args, [](Expression * var ){ 1094 1210 return new SingleInit( new UntypedExpr( 1095 new NameExpr( " get_monitor" ),1211 new NameExpr( "__get_pointer" ), 1096 1212 { var } 1097 1213 ) ); … … 1099 1215 ) 1100 1216 ); 1217 1218 StructInstType * lock_guard_struct = new StructInstType( noQualifiers, lock_guard_decl ); 1219 TypeExpr * lock_type_expr = new TypeExpr( new TypeofType( noQualifiers, args.front()->clone() ) ); 1220 1221 lock_guard_struct->parameters.push_back( lock_type_expr ) ; 1101 1222 1102 1223 // in reverse order : … … 1108 1229 LinkageSpec::Cforall, 1109 1230 nullptr, 1110 new StructInstType( 1111 noQualifiers, 1112 guard_decl 1113 ), 1231 lock_guard_struct, 1114 1232 new ListInit( 1115 1233 { -
tests/Makefile.am
r6c2dc00 r52fad0c 82 82 concurrent/clib_tls.c \ 83 83 exceptions/with-threads.hfa \ 84 exceptions/except-io.hfa \ 85 unified_locking/mutex_test.hfa 84 exceptions/except-io.hfa 86 85 87 86 dist-hook: -
tests/concurrent/mutexstmt/locks.cfa
r6c2dc00 r52fad0c 1 #include <mutex_stmt _locks.hfa>1 #include <mutex_stmt.hfa> 2 2 #include <locks.hfa> 3 3 … … 13 13 for (unsigned int i = 0; i < num_times; i++) { 14 14 mutex ( m1 ) count++; 15 mutex ( m1 ) { 15 mutex ( m1 ) { 16 16 assert(!insideFlag); 17 17 insideFlag = true; … … 65 65 printf("Start Test: single lock mutual exclusion\n"); 66 66 { 67 T_Mutex t[1 0];67 T_Mutex t[1]; 68 68 } 69 69 printf("End Test: single lock mutual exclusion\n"); -
tests/concurrent/mutexstmt/monitors.cfa
r6c2dc00 r52fad0c 1 1 #include <monitor.hfa> 2 #include <mutex_stmt.hfa> 2 3 #include <stdio.h> 3 4 #include <stdlib.hfa> … … 13 14 bool insideFlag = false; 14 15 int count = 0; 16 bool startFlag = false; 15 17 16 18 void main( T_Mutex & this ) {
Note: See TracChangeset
for help on using the changeset viewer.