Changes in src/Concurrency/Keywords.cc [e84ab3d:bbe3719]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
re84ab3d rbbe3719 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; … … 302 303 void postvisit( FunctionDecl * decl ); 303 304 void postvisit( StructDecl * decl ); 305 Statement * postmutate( MutexStmt * stmt ); 304 306 305 307 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first ); … … 307 309 void addDtorStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 308 310 void addStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 311 void addStatements( CompoundStmt * body, const std::list<Expression * > & args ); 309 312 void addThreadDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ); 310 313 … … 312 315 PassVisitor< MutexKeyword > impl; 313 316 acceptAll( translationUnit, impl ); 317 mutateAll( translationUnit, impl ); 314 318 } 315 319 … … 319 323 StructDecl* dtor_guard_decl = nullptr; 320 324 StructDecl* thread_guard_decl = nullptr; 325 StructDecl* lock_guard_decl = nullptr; 321 326 322 327 static std::unique_ptr< Type > generic_func; … … 460 465 } 461 466 462 463 467 void ConcurrentSueKeyword::handle( StructDecl * decl ) { 464 468 if( ! decl->body ) return; … … 476 480 FunctionDecl * func = forwardDeclare( decl ); 477 481 ObjectDecl * field = addField( decl ); 482 483 // add get_.* routine 478 484 addRoutines( field, func ); 485 // add lock/unlock routines to monitors for use by mutex stmt 486 addLockUnlockRoutines( decl ); 479 487 } 480 488 … … 609 617 } 610 618 619 // This function adds the get_.* routine body for coroutines, monitors etc 620 // after their corresponding struct has been made 611 621 void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) { 612 622 CompoundStmt * statement = new CompoundStmt(); … … 631 641 632 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 fixupGenerics(lock_fn_type, decl); 672 fixupGenerics(unlock_fn_type, decl); 673 674 delete this_decl; 675 676 677 ////////////////////////////////////////////////////////////////////// 678 // The following generates this lock routine for all monitors 679 /* 680 void lock (monitor_t & this) { 681 lock(get_monitor(this)); 682 } 683 */ 684 FunctionDecl * lock_decl = new FunctionDecl( 685 "lock", 686 Type::Static, 687 LinkageSpec::Cforall, 688 lock_fn_type, 689 nullptr, 690 { }, 691 Type::Inline 692 ); 693 694 UntypedExpr * get_monitor_lock = new UntypedExpr ( 695 new NameExpr( "get_monitor" ), 696 { new VariableExpr( lock_fn_type->get_parameters().front() ) } 697 ); 698 699 CompoundStmt * lock_statement = new CompoundStmt(); 700 lock_statement->push_back( 701 new ExprStmt( 702 new UntypedExpr ( 703 new NameExpr( "lock" ), 704 { 705 get_monitor_lock 706 } 707 ) 708 ) 709 ); 710 lock_decl->set_statements( lock_statement ); 711 712 ////////////////////////////////////////////////////////////////// 713 // The following generates this routine for all monitors 714 /* 715 void unlock (monitor_t & this) { 716 unlock(get_monitor(this)); 717 } 718 */ 719 FunctionDecl * unlock_decl = new FunctionDecl( 720 "unlock", 721 Type::Static, 722 LinkageSpec::Cforall, 723 unlock_fn_type, 724 nullptr, 725 { }, 726 Type::Inline 727 ); 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 ); 633 751 } 634 752 … … 934 1052 assert( !thread_guard_decl ); 935 1053 thread_guard_decl = decl; 936 } 1054 } 1055 else if ( decl->name == "__mutex_stmt_lock_guard" && decl->body ) { 1056 assert( !lock_guard_decl ); 1057 lock_guard_decl = decl; 1058 } 1059 } 1060 1061 Statement * MutexKeyword::postmutate( MutexStmt * stmt ) { 1062 std::list<Statement *> stmtsForCtor; 1063 stmtsForCtor.push_back(stmt->stmt); 1064 CompoundStmt * body = new CompoundStmt( stmtsForCtor ); 1065 addStatements( body, stmt->mutexObjs); 1066 return body; 937 1067 } 938 1068 … … 1058 1188 )) 1059 1189 ); 1190 } 1191 1192 void MutexKeyword::addStatements( CompoundStmt * body, const std::list<Expression * > & args ) { 1193 ObjectDecl * monitors = new ObjectDecl( 1194 "__monitors", 1195 noStorageClasses, 1196 LinkageSpec::Cforall, 1197 nullptr, 1198 new ArrayType( 1199 noQualifiers, 1200 new PointerType( 1201 noQualifiers, 1202 new TypeofType( noQualifiers, args.front()->clone() ) 1203 ), 1204 new ConstantExpr( Constant::from_ulong( args.size() ) ), 1205 false, 1206 false 1207 ), 1208 new ListInit( 1209 map_range < std::list<Initializer*> > ( args, [](Expression * var ){ 1210 return new SingleInit( new AddressExpr( var ) ); 1211 }) 1212 ) 1213 ); 1214 1215 StructInstType * lock_guard_struct = new StructInstType( noQualifiers, lock_guard_decl ); 1216 TypeExpr * lock_type_expr = new TypeExpr( new TypeofType( noQualifiers, args.front()->clone() ) ); 1217 1218 lock_guard_struct->parameters.push_back( lock_type_expr ) ; 1219 1220 // in reverse order : 1221 // monitor_guard_t __guard = { __monitors, # }; 1222 body->push_front( 1223 new DeclStmt( new ObjectDecl( 1224 "__guard", 1225 noStorageClasses, 1226 LinkageSpec::Cforall, 1227 nullptr, 1228 lock_guard_struct, 1229 new ListInit( 1230 { 1231 new SingleInit( new VariableExpr( monitors ) ), 1232 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ) 1233 }, 1234 noDesignators, 1235 true 1236 ) 1237 )) 1238 ); 1239 1240 //monitor$ * __monitors[] = { get_monitor(a), get_monitor(b) }; 1241 body->push_front( new DeclStmt( monitors) ); 1060 1242 } 1061 1243
Note:
See TracChangeset
for help on using the changeset viewer.