Changeset 1cb758f2
- Timestamp:
- Aug 27, 2017, 11:26:26 AM (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:
- 111a8af8, 26238c1, 7ee1e2f6
- Parents:
- 0c6596f (diff), eca3d10 (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. - Location:
- src
- Files:
-
- 3 added
- 1 deleted
- 21 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r0c6596f r1cb758f2 201 201 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* ); 202 202 void validate( DeclarationWithType * ); 203 void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);203 void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 204 204 205 205 static void implement( std::list< Declaration * > & translationUnit ) { … … 211 211 StructDecl* monitor_decl = nullptr; 212 212 StructDecl* guard_decl = nullptr; 213 214 static std::unique_ptr< Type > generic_func; 213 215 }; 216 217 std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >( 218 new FunctionType( 219 noQualifiers, 220 true 221 ) 222 ); 214 223 215 224 //----------------------------------------------------------------------------- … … 395 404 // Mutex keyword implementation 396 405 //============================================================================================= 406 397 407 void MutexKeyword::visit(FunctionDecl* decl) { 398 408 Visitor::visit(decl); … … 411 421 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 412 422 413 addStatments( body, mutexArgs );423 addStatments( decl, body, mutexArgs ); 414 424 } 415 425 … … 458 468 } 459 469 460 void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {470 void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 461 471 ObjectDecl * monitors = new ObjectDecl( 462 472 "__monitors", … … 489 499 ); 490 500 501 assert(generic_func); 502 491 503 //in reverse order : 492 // monitor_guard_t __guard = { __monitors, # };504 // monitor_guard_t __guard = { __monitors, #, func }; 493 505 body->push_front( 494 506 new DeclStmt( noLabels, new ObjectDecl( … … 504 516 { 505 517 new SingleInit( new VariableExpr( monitors ) ), 506 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ) 518 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ), 519 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) ) 507 520 }, 508 521 noDesignators, -
src/Parser/ParseNode.h
r0c6596f r1cb758f2 414 414 Statement * build_compound( StatementNode * first ); 415 415 Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr ); 416 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when ); 417 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing ); 418 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 419 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 416 420 417 421 //############################################################################## -
src/Parser/StatementNode.cc
r0c6596f r1cb758f2 93 93 elseb = branches.front(); 94 94 } // if 95 95 96 96 std::list< Statement * > init; 97 97 if ( ctl->init != 0 ) { … … 207 207 } 208 208 209 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) { 210 auto node = new WaitForStmt(); 211 212 WaitForStmt::Target target; 213 target.function = maybeBuild<Expression>( targetExpr ); 214 buildMoveList< Expression >( targetExpr, target.arguments ); 215 delete targetExpr; 216 217 node->clauses.push_back( WaitForStmt::Clause{ 218 target, 219 maybeMoveBuild<Statement >( stmt ), 220 maybeMoveBuild<Expression>( when ) 221 }); 222 223 return node; 224 } 225 226 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) { 227 WaitForStmt::Target target; 228 229 target.function = maybeBuild<Expression>( targetExpr ); 230 buildMoveList< Expression >( targetExpr, target.arguments ); 231 delete targetExpr; 232 233 node->clauses.push_back( WaitForStmt::Clause{ 234 std::move( target ), 235 maybeMoveBuild<Statement >( stmt ), 236 maybeMoveBuild<Expression>( when ) 237 }); 238 239 return node; 240 } 241 242 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) { 243 auto node = new WaitForStmt(); 244 245 if( timeout ) { 246 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 247 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 248 node->timeout.condition = maybeMoveBuild<Expression>( when ); 249 } 250 else { 251 node->orelse.statement = maybeMoveBuild<Statement >( stmt ); 252 node->orelse.condition = maybeMoveBuild<Expression>( when ); 253 } 254 255 return node; 256 } 257 258 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ) { 259 auto node = new WaitForStmt(); 260 261 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 262 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 263 node->timeout.condition = maybeMoveBuild<Expression>( when ); 264 265 node->orelse.statement = maybeMoveBuild<Statement >( else_stmt ); 266 node->orelse.condition = maybeMoveBuild<Expression>( else_when ); 267 268 return node; 269 } 270 271 // WaitForStmt::Target build_waitfor( const std::string * name, ExpressionNode * arguments ) { 272 // return WaitForStmt::Clause{ 273 274 // }; 275 // } 276 209 277 Statement *build_compound( StatementNode *first ) { 210 278 CompoundStmt *cs = new CompoundStmt( noLabels ); -
src/Parser/parser.yy
r0c6596f r1cb758f2 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 23 21:08:08201713 // Update Count : 27 0412 // Last Modified On : Sat Aug 26 17:50:19 2017 13 // Update Count : 2712 14 14 // 15 15 … … 97 97 DeclarationNode::TypeClass tclass; 98 98 StatementNode * sn; 99 WaitForStmt * wfs; 99 100 ConstantExpr * constant; 100 101 IfCtl * ifctl; … … 119 120 %token RESTRICT // C99 120 121 %token ATOMIC // C11 121 %token FORALL MUTEX VIRTUAL // CFA122 %token FORALL MUTEX VIRTUAL // CFA 122 123 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 123 124 %token BOOL COMPLEX IMAGINARY // C99 … … 189 190 190 191 // statements 191 %type<sn> labeled_statement compound_statement expression_statement selection_statement 192 %type<sn> iteration_statement jump_statement 193 %type<sn> with_statement exception_statement asm_statement 194 %type<sn> when_clause_opt waitfor_statement waitfor_clause waitfor timeout 195 %type<sn> fall_through_opt fall_through 196 %type<sn> statement statement_list 197 %type<sn> block_item_list block_item 198 %type<sn> with_clause_opt 192 %type<sn> statement labeled_statement compound_statement 193 %type<sn> statement_decl statement_decl_list statement_list_nodecl 194 %type<sn> selection_statement 195 %type<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list 199 196 %type<en> case_value 200 197 %type<sn> case_clause case_value_list case_label case_label_list 201 %type<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list 202 %type<sn> handler_clause finally_clause 198 %type<sn> fall_through fall_through_opt 199 %type<sn> iteration_statement jump_statement 200 %type<sn> expression_statement asm_statement 201 %type<sn> with_statement with_clause_opt 202 %type<sn> exception_statement handler_clause finally_clause 203 203 %type<catch_kind> handler_key 204 %type<en> when_clause when_clause_opt waitfor timeout 205 %type<sn> waitfor_statement 206 %type<wfs> waitfor_clause 204 207 205 208 // declarations … … 773 776 push push 774 777 local_label_declaration_opt // GCC, local labels 775 block_item_list// C99, intermix declarations and statements778 statement_decl_list // C99, intermix declarations and statements 776 779 pop '}' 777 780 { $$ = new StatementNode( build_compound( $5 ) ); } 778 781 ; 779 782 780 block_item_list:// C99781 block_item782 | block_item_list push block_item783 statement_decl_list: // C99 784 statement_decl 785 | statement_decl_list push statement_decl 783 786 { if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } } 784 787 ; 785 788 786 block_item:789 statement_decl: 787 790 declaration // CFA, new & old style declarations 788 791 { $$ = new StatementNode( $1 ); } … … 802 805 ; 803 806 804 statement_list :807 statement_list_nodecl: 805 808 statement 806 | statement_list statement809 | statement_list_nodecl statement 807 810 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } } 808 811 ; … … 814 817 815 818 selection_statement: 816 IF '(' push if_control_expression ')' statement 819 IF '(' push if_control_expression ')' statement %prec THEN 817 820 // explicitly deal with the shift/reduce conflict on if/else 818 821 { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); } … … 889 892 890 893 switch_clause_list: // CFA 891 case_label_list statement_list 894 case_label_list statement_list_nodecl 892 895 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); } 893 | switch_clause_list case_label_list statement_list 896 | switch_clause_list case_label_list statement_list_nodecl 894 897 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); } 895 898 ; … … 904 907 case_label_list fall_through 905 908 { $$ = $1->append_last_case( $2 ); } 906 | case_label_list statement_list fall_through_opt909 | case_label_list statement_list_nodecl fall_through_opt 907 910 { $$ = $1->append_last_case( new StatementNode( build_compound( (StatementNode *)$2->set_last( $3 ) ) ) ); } 908 911 | choose_clause_list case_label_list fall_through 909 912 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( $3 ))); } 910 | choose_clause_list case_label_list statement_list fall_through_opt913 | choose_clause_list case_label_list statement_list_nodecl fall_through_opt 911 914 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( (StatementNode *)$3->set_last( $4 ) ) ) ) ) ); } 912 915 ; … … 977 980 ; 978 981 982 when_clause: 983 WHEN '(' comma_expression ')' 984 { $$ = $3; } 985 ; 986 979 987 when_clause_opt: 980 988 // empty 981 { $$ = nullptr; } // FIX ME 982 | WHEN '(' comma_expression ')' 983 { $$ = nullptr; } // FIX ME 989 { $$ = nullptr; } 990 | when_clause 984 991 ; 985 992 986 993 waitfor: 987 994 WAITFOR '(' identifier ')' 988 { $$ = nullptr; } // FIX ME 995 { 996 $$ = new ExpressionNode( new NameExpr( *$3 ) ); 997 delete $3; 998 } 989 999 | WAITFOR '(' identifier ',' argument_expression_list ')' 990 { $$ = nullptr; } // FIX ME 1000 { 1001 $$ = new ExpressionNode( new NameExpr( *$3 ) ); 1002 $$->set_last( $5 ); 1003 delete $3; 1004 } 991 1005 ; 992 1006 993 1007 timeout: 994 1008 TIMEOUT '(' comma_expression ')' 995 { $$ = nullptr; } // FIX ME1009 { $$ = $3; } 996 1010 ; 997 1011 998 1012 waitfor_clause: 999 when_clause_opt waitfor statement 1000 { $$ = nullptr; } // FIX ME1013 when_clause_opt waitfor statement %prec THEN 1014 { $$ = build_waitfor( $2, $3, $1 ); } 1001 1015 | when_clause_opt waitfor statement WOR waitfor_clause 1002 { $$ = nullptr; } // FIX ME1003 | when_clause_opt timeout statement 1004 { $$ = nullptr; } // FIX ME1016 { $$ = build_waitfor( $2, $3, $1, $5 ); } 1017 | when_clause_opt timeout statement %prec THEN 1018 { $$ = build_waitfor_timeout( $2, $3, $1 ); } 1005 1019 | when_clause_opt ELSE statement 1006 { $$ = nullptr; } // FIX ME 1007 | when_clause_opt timeout statement WOR when_clause_opt ELSE statement 1008 { $$ = nullptr; } // FIX ME 1020 { $$ = build_waitfor_timeout( nullptr, $3, $1 ); } 1021 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1022 | when_clause_opt timeout statement WOR when_clause ELSE statement 1023 { $$ = build_waitfor_timeout( $2, $3, $1, $7, $5 ); } 1009 1024 ; 1010 1025 1011 1026 waitfor_statement: 1012 when_clause_opt waitfor statement 1013 { $$ = n ullptr; } // FIX ME1027 when_clause_opt waitfor statement %prec THEN 1028 { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); } 1014 1029 | when_clause_opt waitfor statement WOR waitfor_clause 1015 { $$ = n ullptr; } // FIX ME1030 { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); } 1016 1031 ; 1017 1032 -
src/SynTree/Mutator.cc
r0c6596f r1cb758f2 32 32 Mutator::~Mutator() {} 33 33 34 DeclarationWithType * Mutator::mutate( ObjectDecl *objectDecl ) {34 DeclarationWithType * Mutator::mutate( ObjectDecl *objectDecl ) { 35 35 objectDecl->set_type( maybeMutate( objectDecl->get_type(), *this ) ); 36 36 objectDecl->set_init( maybeMutate( objectDecl->get_init(), *this ) ); … … 39 39 } 40 40 41 DeclarationWithType * Mutator::mutate( FunctionDecl *functionDecl ) {41 DeclarationWithType * Mutator::mutate( FunctionDecl *functionDecl ) { 42 42 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 43 43 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); … … 45 45 } 46 46 47 Declaration * Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {47 Declaration * Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) { 48 48 mutateAll( aggregateDecl->get_parameters(), *this ); 49 49 mutateAll( aggregateDecl->get_members(), *this ); … … 51 51 } 52 52 53 Declaration * Mutator::mutate( StructDecl *aggregateDecl ) {53 Declaration * Mutator::mutate( StructDecl *aggregateDecl ) { 54 54 handleAggregateDecl( aggregateDecl ); 55 55 return aggregateDecl; 56 56 } 57 57 58 Declaration * Mutator::mutate( UnionDecl *aggregateDecl ) {58 Declaration * Mutator::mutate( UnionDecl *aggregateDecl ) { 59 59 handleAggregateDecl( aggregateDecl ); 60 60 return aggregateDecl; 61 61 } 62 62 63 Declaration * Mutator::mutate( EnumDecl *aggregateDecl ) {63 Declaration * Mutator::mutate( EnumDecl *aggregateDecl ) { 64 64 handleAggregateDecl( aggregateDecl ); 65 65 return aggregateDecl; 66 66 } 67 67 68 Declaration * Mutator::mutate( TraitDecl *aggregateDecl ) {68 Declaration * Mutator::mutate( TraitDecl *aggregateDecl ) { 69 69 handleAggregateDecl( aggregateDecl ); 70 70 return aggregateDecl; 71 71 } 72 72 73 Declaration * Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {73 Declaration * Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) { 74 74 mutateAll( typeDecl->get_parameters(), *this ); 75 75 mutateAll( typeDecl->get_assertions(), *this ); … … 78 78 } 79 79 80 TypeDecl * Mutator::mutate( TypeDecl *typeDecl ) {80 TypeDecl * Mutator::mutate( TypeDecl *typeDecl ) { 81 81 handleNamedTypeDecl( typeDecl ); 82 82 typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) ); … … 84 84 } 85 85 86 Declaration * Mutator::mutate( TypedefDecl *typeDecl ) {86 Declaration * Mutator::mutate( TypedefDecl *typeDecl ) { 87 87 handleNamedTypeDecl( typeDecl ); 88 88 return typeDecl; 89 89 } 90 90 91 AsmDecl * Mutator::mutate( AsmDecl *asmDecl ) {91 AsmDecl * Mutator::mutate( AsmDecl *asmDecl ) { 92 92 asmDecl->set_stmt( maybeMutate( asmDecl->get_stmt(), *this ) ); 93 93 return asmDecl; … … 95 95 96 96 97 CompoundStmt * Mutator::mutate( CompoundStmt *compoundStmt ) {97 CompoundStmt * Mutator::mutate( CompoundStmt *compoundStmt ) { 98 98 mutateAll( compoundStmt->get_kids(), *this ); 99 99 return compoundStmt; 100 100 } 101 101 102 Statement * Mutator::mutate( ExprStmt *exprStmt ) {102 Statement * Mutator::mutate( ExprStmt *exprStmt ) { 103 103 exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) ); 104 104 return exprStmt; 105 105 } 106 106 107 Statement * Mutator::mutate( AsmStmt *asmStmt ) {107 Statement * Mutator::mutate( AsmStmt *asmStmt ) { 108 108 asmStmt->set_instruction( maybeMutate( asmStmt->get_instruction(), *this ) ); 109 109 mutateAll( asmStmt->get_output(), *this ); … … 113 113 } 114 114 115 Statement * Mutator::mutate( IfStmt *ifStmt ) {115 Statement * Mutator::mutate( IfStmt *ifStmt ) { 116 116 mutateAll( ifStmt->get_initialization(), *this ); 117 117 ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) ); … … 121 121 } 122 122 123 Statement * Mutator::mutate( WhileStmt *whileStmt ) {123 Statement * Mutator::mutate( WhileStmt *whileStmt ) { 124 124 whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) ); 125 125 whileStmt->set_body( maybeMutate( whileStmt->get_body(), *this ) ); … … 127 127 } 128 128 129 Statement * Mutator::mutate( ForStmt *forStmt ) {129 Statement * Mutator::mutate( ForStmt *forStmt ) { 130 130 mutateAll( forStmt->get_initialization(), *this ); 131 131 forStmt->set_condition( maybeMutate( forStmt->get_condition(), *this ) ); … … 135 135 } 136 136 137 Statement * Mutator::mutate( SwitchStmt *switchStmt ) {137 Statement * Mutator::mutate( SwitchStmt *switchStmt ) { 138 138 switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) ); 139 139 mutateAll( switchStmt->get_statements(), *this ); … … 141 141 } 142 142 143 Statement * Mutator::mutate( CaseStmt *caseStmt ) {143 Statement * Mutator::mutate( CaseStmt *caseStmt ) { 144 144 caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) ); 145 145 mutateAll (caseStmt->get_statements(), *this ); … … 148 148 } 149 149 150 Statement * Mutator::mutate( BranchStmt *branchStmt ) {150 Statement * Mutator::mutate( BranchStmt *branchStmt ) { 151 151 return branchStmt; 152 152 } 153 153 154 Statement * Mutator::mutate( ReturnStmt *returnStmt ) {154 Statement * Mutator::mutate( ReturnStmt *returnStmt ) { 155 155 returnStmt->set_expr( maybeMutate( returnStmt->get_expr(), *this ) ); 156 156 return returnStmt; 157 157 } 158 158 159 Statement * Mutator::mutate( ThrowStmt *throwStmt ) {159 Statement * Mutator::mutate( ThrowStmt *throwStmt ) { 160 160 throwStmt->set_expr( maybeMutate( throwStmt->get_expr(), *this ) ); 161 161 throwStmt->set_target( maybeMutate( throwStmt->get_target(), *this ) ); … … 163 163 } 164 164 165 Statement * Mutator::mutate( TryStmt *tryStmt ) {165 Statement * Mutator::mutate( TryStmt *tryStmt ) { 166 166 tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); 167 167 mutateAll( tryStmt->get_catchers(), *this ); … … 170 170 } 171 171 172 Statement * Mutator::mutate( CatchStmt *catchStmt ) {172 Statement * Mutator::mutate( CatchStmt *catchStmt ) { 173 173 catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) ); 174 174 catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) ); … … 177 177 } 178 178 179 Statement * Mutator::mutate( FinallyStmt *finalStmt ) {179 Statement * Mutator::mutate( FinallyStmt *finalStmt ) { 180 180 finalStmt->set_block( maybeMutate( finalStmt->get_block(), *this ) ); 181 181 return finalStmt; 182 182 } 183 183 184 NullStmt *Mutator::mutate( NullStmt *nullStmt ) { 184 Statement * Mutator::mutate( WaitForStmt *waitforStmt ) { 185 for( auto & clause : waitforStmt->clauses ) { 186 clause.target.function = maybeMutate( clause.target.function, *this ); 187 mutateAll( clause.target.arguments, *this ); 188 189 clause.statement = maybeMutate( clause.statement, *this ); 190 clause.condition = maybeMutate( clause.condition, *this ); 191 } 192 193 waitforStmt->timeout.time = maybeMutate( waitforStmt->timeout.time, *this ); 194 waitforStmt->timeout.statement = maybeMutate( waitforStmt->timeout.statement, *this ); 195 waitforStmt->timeout.condition = maybeMutate( waitforStmt->timeout.condition, *this ); 196 waitforStmt->orelse.statement = maybeMutate( waitforStmt->orelse.statement, *this ); 197 waitforStmt->orelse.condition = maybeMutate( waitforStmt->orelse.condition, *this ); 198 199 return waitforStmt; 200 } 201 202 NullStmt * Mutator::mutate( NullStmt *nullStmt ) { 185 203 return nullStmt; 186 204 } 187 205 188 Statement * Mutator::mutate( DeclStmt *declStmt ) {206 Statement * Mutator::mutate( DeclStmt *declStmt ) { 189 207 declStmt->set_decl( maybeMutate( declStmt->get_decl(), *this ) ); 190 208 return declStmt; 191 209 } 192 210 193 Statement * Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {211 Statement * Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) { 194 212 impCtorDtorStmt->set_callStmt( maybeMutate( impCtorDtorStmt->get_callStmt(), *this ) ); 195 213 return impCtorDtorStmt; … … 197 215 198 216 199 Expression * Mutator::mutate( ApplicationExpr *applicationExpr ) {217 Expression * Mutator::mutate( ApplicationExpr *applicationExpr ) { 200 218 applicationExpr->set_env( maybeMutate( applicationExpr->get_env(), *this ) ); 201 219 applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) ); … … 205 223 } 206 224 207 Expression * Mutator::mutate( UntypedExpr *untypedExpr ) {225 Expression * Mutator::mutate( UntypedExpr *untypedExpr ) { 208 226 untypedExpr->set_env( maybeMutate( untypedExpr->get_env(), *this ) ); 209 227 untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) ); … … 212 230 } 213 231 214 Expression * Mutator::mutate( NameExpr *nameExpr ) {232 Expression * Mutator::mutate( NameExpr *nameExpr ) { 215 233 nameExpr->set_env( maybeMutate( nameExpr->get_env(), *this ) ); 216 234 nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) ); … … 218 236 } 219 237 220 Expression * Mutator::mutate( AddressExpr *addressExpr ) {238 Expression * Mutator::mutate( AddressExpr *addressExpr ) { 221 239 addressExpr->set_env( maybeMutate( addressExpr->get_env(), *this ) ); 222 240 addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) ); … … 225 243 } 226 244 227 Expression * Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {245 Expression * Mutator::mutate( LabelAddressExpr *labelAddressExpr ) { 228 246 labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) ); 229 247 labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) ); … … 232 250 } 233 251 234 Expression * Mutator::mutate( CastExpr *castExpr ) {252 Expression * Mutator::mutate( CastExpr *castExpr ) { 235 253 castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) ); 236 254 castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) ); … … 239 257 } 240 258 241 Expression * Mutator::mutate( VirtualCastExpr *castExpr ) {259 Expression * Mutator::mutate( VirtualCastExpr *castExpr ) { 242 260 castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) ); 243 261 castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) ); … … 246 264 } 247 265 248 Expression * Mutator::mutate( UntypedMemberExpr *memberExpr ) {266 Expression * Mutator::mutate( UntypedMemberExpr *memberExpr ) { 249 267 memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) ); 250 268 memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) ); … … 254 272 } 255 273 256 Expression * Mutator::mutate( MemberExpr *memberExpr ) {274 Expression * Mutator::mutate( MemberExpr *memberExpr ) { 257 275 memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) ); 258 276 memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) ); … … 261 279 } 262 280 263 Expression * Mutator::mutate( VariableExpr *variableExpr ) {281 Expression * Mutator::mutate( VariableExpr *variableExpr ) { 264 282 variableExpr->set_env( maybeMutate( variableExpr->get_env(), *this ) ); 265 283 variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) ); … … 267 285 } 268 286 269 Expression * Mutator::mutate( ConstantExpr *constantExpr ) {287 Expression * Mutator::mutate( ConstantExpr *constantExpr ) { 270 288 constantExpr->set_env( maybeMutate( constantExpr->get_env(), *this ) ); 271 289 constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) ); … … 274 292 } 275 293 276 Expression * Mutator::mutate( SizeofExpr *sizeofExpr ) {294 Expression * Mutator::mutate( SizeofExpr *sizeofExpr ) { 277 295 sizeofExpr->set_env( maybeMutate( sizeofExpr->get_env(), *this ) ); 278 296 sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) ); … … 285 303 } 286 304 287 Expression * Mutator::mutate( AlignofExpr *alignofExpr ) {305 Expression * Mutator::mutate( AlignofExpr *alignofExpr ) { 288 306 alignofExpr->set_env( maybeMutate( alignofExpr->get_env(), *this ) ); 289 307 alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) ); … … 296 314 } 297 315 298 Expression * Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {316 Expression * Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) { 299 317 offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) ); 300 318 offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) ); … … 303 321 } 304 322 305 Expression * Mutator::mutate( OffsetofExpr *offsetofExpr ) {323 Expression * Mutator::mutate( OffsetofExpr *offsetofExpr ) { 306 324 offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) ); 307 325 offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) ); … … 311 329 } 312 330 313 Expression * Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {331 Expression * Mutator::mutate( OffsetPackExpr *offsetPackExpr ) { 314 332 offsetPackExpr->set_env( maybeMutate( offsetPackExpr->get_env(), *this ) ); 315 333 offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) ); … … 318 336 } 319 337 320 Expression * Mutator::mutate( AttrExpr *attrExpr ) {338 Expression * Mutator::mutate( AttrExpr *attrExpr ) { 321 339 attrExpr->set_env( maybeMutate( attrExpr->get_env(), *this ) ); 322 340 attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) ); … … 329 347 } 330 348 331 Expression * Mutator::mutate( LogicalExpr *logicalExpr ) {349 Expression * Mutator::mutate( LogicalExpr *logicalExpr ) { 332 350 logicalExpr->set_env( maybeMutate( logicalExpr->get_env(), *this ) ); 333 351 logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) ); … … 337 355 } 338 356 339 Expression * Mutator::mutate( ConditionalExpr *conditionalExpr ) {357 Expression * Mutator::mutate( ConditionalExpr *conditionalExpr ) { 340 358 conditionalExpr->set_env( maybeMutate( conditionalExpr->get_env(), *this ) ); 341 359 conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) ); … … 346 364 } 347 365 348 Expression * Mutator::mutate( CommaExpr *commaExpr ) {366 Expression * Mutator::mutate( CommaExpr *commaExpr ) { 349 367 commaExpr->set_env( maybeMutate( commaExpr->get_env(), *this ) ); 350 368 commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) ); … … 354 372 } 355 373 356 Expression * Mutator::mutate( TypeExpr *typeExpr ) {374 Expression * Mutator::mutate( TypeExpr *typeExpr ) { 357 375 typeExpr->set_env( maybeMutate( typeExpr->get_env(), *this ) ); 358 376 typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) ); … … 361 379 } 362 380 363 Expression * Mutator::mutate( AsmExpr *asmExpr ) {381 Expression * Mutator::mutate( AsmExpr *asmExpr ) { 364 382 asmExpr->set_env( maybeMutate( asmExpr->get_env(), *this ) ); 365 383 asmExpr->set_inout( maybeMutate( asmExpr->get_inout(), *this ) ); … … 386 404 } 387 405 388 Expression * Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {406 Expression * Mutator::mutate( CompoundLiteralExpr *compLitExpr ) { 389 407 compLitExpr->set_env( maybeMutate( compLitExpr->get_env(), *this ) ); 390 408 compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) ); … … 393 411 } 394 412 395 Expression * Mutator::mutate( RangeExpr *rangeExpr ) {413 Expression * Mutator::mutate( RangeExpr *rangeExpr ) { 396 414 rangeExpr->set_env( maybeMutate( rangeExpr->get_env(), *this ) ); 397 415 rangeExpr->set_low( maybeMutate( rangeExpr->get_low(), *this ) ); … … 400 418 } 401 419 402 Expression * Mutator::mutate( UntypedTupleExpr *tupleExpr ) {420 Expression * Mutator::mutate( UntypedTupleExpr *tupleExpr ) { 403 421 tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) ); 404 422 tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) ); … … 407 425 } 408 426 409 Expression * Mutator::mutate( TupleExpr *tupleExpr ) {427 Expression * Mutator::mutate( TupleExpr *tupleExpr ) { 410 428 tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) ); 411 429 tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) ); … … 414 432 } 415 433 416 Expression * Mutator::mutate( TupleIndexExpr *tupleExpr ) {434 Expression * Mutator::mutate( TupleIndexExpr *tupleExpr ) { 417 435 tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) ); 418 436 tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) ); … … 421 439 } 422 440 423 Expression * Mutator::mutate( TupleAssignExpr *assignExpr ) {441 Expression * Mutator::mutate( TupleAssignExpr *assignExpr ) { 424 442 assignExpr->set_env( maybeMutate( assignExpr->get_env(), *this ) ); 425 443 assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) ); … … 428 446 } 429 447 430 Expression * Mutator::mutate( StmtExpr *stmtExpr ) {448 Expression * Mutator::mutate( StmtExpr *stmtExpr ) { 431 449 stmtExpr->set_env( maybeMutate( stmtExpr->get_env(), *this ) ); 432 450 stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) ); … … 437 455 } 438 456 439 Expression * Mutator::mutate( UniqueExpr *uniqueExpr ) {457 Expression * Mutator::mutate( UniqueExpr *uniqueExpr ) { 440 458 uniqueExpr->set_env( maybeMutate( uniqueExpr->get_env(), *this ) ); 441 459 uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) ); … … 444 462 } 445 463 446 Expression * Mutator::mutate( UntypedInitExpr * initExpr ) {464 Expression * Mutator::mutate( UntypedInitExpr * initExpr ) { 447 465 initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) ); 448 466 initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) ); … … 452 470 } 453 471 454 Expression * Mutator::mutate( InitExpr * initExpr ) {472 Expression * Mutator::mutate( InitExpr * initExpr ) { 455 473 initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) ); 456 474 initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) ); … … 461 479 462 480 463 Type * Mutator::mutate( VoidType *voidType ) {481 Type * Mutator::mutate( VoidType *voidType ) { 464 482 mutateAll( voidType->get_forall(), *this ); 465 483 return voidType; 466 484 } 467 485 468 Type * Mutator::mutate( BasicType *basicType ) {486 Type * Mutator::mutate( BasicType *basicType ) { 469 487 mutateAll( basicType->get_forall(), *this ); 470 488 return basicType; 471 489 } 472 490 473 Type * Mutator::mutate( PointerType *pointerType ) {491 Type * Mutator::mutate( PointerType *pointerType ) { 474 492 mutateAll( pointerType->get_forall(), *this ); 475 493 pointerType->set_base( maybeMutate( pointerType->get_base(), *this ) ); … … 477 495 } 478 496 479 Type * Mutator::mutate( ArrayType *arrayType ) {497 Type * Mutator::mutate( ArrayType *arrayType ) { 480 498 mutateAll( arrayType->get_forall(), *this ); 481 499 arrayType->set_dimension( maybeMutate( arrayType->get_dimension(), *this ) ); … … 484 502 } 485 503 486 Type * Mutator::mutate( ReferenceType *refType ) {504 Type * Mutator::mutate( ReferenceType * refType ) { 487 505 mutateAll( refType->get_forall(), *this ); 488 506 refType->set_base( maybeMutate( refType->get_base(), *this ) ); … … 490 508 } 491 509 492 Type * Mutator::mutate( FunctionType *functionType ) {510 Type * Mutator::mutate( FunctionType * functionType ) { 493 511 mutateAll( functionType->get_forall(), *this ); 494 512 mutateAll( functionType->get_returnVals(), *this ); … … 497 515 } 498 516 499 Type * Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {517 Type * Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) { 500 518 mutateAll( aggregateUseType->get_forall(), *this ); 501 519 mutateAll( aggregateUseType->get_parameters(), *this ); … … 503 521 } 504 522 505 Type * Mutator::mutate( StructInstType *aggregateUseType ) {523 Type * Mutator::mutate( StructInstType *aggregateUseType ) { 506 524 handleReferenceToType( aggregateUseType ); 507 525 return aggregateUseType; 508 526 } 509 527 510 Type * Mutator::mutate( UnionInstType *aggregateUseType ) {528 Type * Mutator::mutate( UnionInstType *aggregateUseType ) { 511 529 handleReferenceToType( aggregateUseType ); 512 530 return aggregateUseType; 513 531 } 514 532 515 Type * Mutator::mutate( EnumInstType *aggregateUseType ) {533 Type * Mutator::mutate( EnumInstType *aggregateUseType ) { 516 534 handleReferenceToType( aggregateUseType ); 517 535 return aggregateUseType; 518 536 } 519 537 520 Type * Mutator::mutate( TraitInstType *aggregateUseType ) {538 Type * Mutator::mutate( TraitInstType *aggregateUseType ) { 521 539 handleReferenceToType( aggregateUseType ); 522 540 mutateAll( aggregateUseType->get_members(), *this ); … … 524 542 } 525 543 526 Type * Mutator::mutate( TypeInstType *aggregateUseType ) {544 Type * Mutator::mutate( TypeInstType *aggregateUseType ) { 527 545 handleReferenceToType( aggregateUseType ); 528 546 return aggregateUseType; 529 547 } 530 548 531 Type * Mutator::mutate( TupleType *tupleType ) {549 Type * Mutator::mutate( TupleType *tupleType ) { 532 550 mutateAll( tupleType->get_forall(), *this ); 533 551 mutateAll( tupleType->get_types(), *this ); … … 536 554 } 537 555 538 Type * Mutator::mutate( TypeofType *typeofType ) {556 Type * Mutator::mutate( TypeofType *typeofType ) { 539 557 assert( typeofType->get_expr() ); 540 558 typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) ); … … 542 560 } 543 561 544 Type * Mutator::mutate( AttrType *attrType ) {562 Type * Mutator::mutate( AttrType *attrType ) { 545 563 if ( attrType->get_isType() ) { 546 564 assert( attrType->get_type() ); … … 553 571 } 554 572 555 Type * Mutator::mutate( VarArgsType *varArgsType ) {573 Type * Mutator::mutate( VarArgsType *varArgsType ) { 556 574 mutateAll( varArgsType->get_forall(), *this ); 557 575 return varArgsType; 558 576 } 559 577 560 Type * Mutator::mutate( ZeroType *zeroType ) {578 Type * Mutator::mutate( ZeroType *zeroType ) { 561 579 mutateAll( zeroType->get_forall(), *this ); 562 580 return zeroType; 563 581 } 564 582 565 Type * Mutator::mutate( OneType *oneType ) {583 Type * Mutator::mutate( OneType *oneType ) { 566 584 mutateAll( oneType->get_forall(), *this ); 567 585 return oneType; … … 569 587 570 588 571 Designation * Mutator::mutate( Designation * designation ) {589 Designation * Mutator::mutate( Designation * designation ) { 572 590 mutateAll( designation->get_designators(), *this ); 573 591 return designation; 574 592 } 575 593 576 Initializer * Mutator::mutate( SingleInit *singleInit ) {594 Initializer * Mutator::mutate( SingleInit *singleInit ) { 577 595 singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) ); 578 596 return singleInit; 579 597 } 580 598 581 Initializer * Mutator::mutate( ListInit *listInit ) {599 Initializer * Mutator::mutate( ListInit *listInit ) { 582 600 mutateAll( listInit->get_designations(), *this ); 583 601 mutateAll( listInit->get_initializers(), *this ); … … 585 603 } 586 604 587 Initializer * Mutator::mutate( ConstructorInit *ctorInit ) {605 Initializer * Mutator::mutate( ConstructorInit *ctorInit ) { 588 606 ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) ); 589 607 ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) ); … … 593 611 594 612 595 Subrange * Mutator::mutate( Subrange *subrange ) {613 Subrange * Mutator::mutate( Subrange *subrange ) { 596 614 return subrange; 597 615 } 598 616 599 617 600 Constant * Mutator::mutate( Constant *constant ) {618 Constant * Mutator::mutate( Constant *constant ) { 601 619 return constant; 602 620 } -
src/SynTree/Mutator.h
r0c6596f r1cb758f2 49 49 virtual Statement* mutate( CatchStmt *catchStmt ); 50 50 virtual Statement* mutate( FinallyStmt *catchStmt ); 51 virtual Statement* mutate( WaitForStmt *waitforStmt ); 51 52 virtual NullStmt* mutate( NullStmt *nullStmt ); 52 53 virtual Statement* mutate( DeclStmt *declStmt ); -
src/SynTree/Statement.cc
r0c6596f r1cb758f2 419 419 } 420 420 421 WaitForStmt::WaitForStmt( std::list<Label> labels ) : Statement( labels ) { 422 timeout.time = nullptr; 423 timeout.statement = nullptr; 424 timeout.condition = nullptr; 425 orelse .statement = nullptr; 426 orelse .condition = nullptr; 427 } 428 429 WaitForStmt::WaitForStmt( const WaitForStmt & other ) : Statement( other ) { 430 clauses.reserve( other.clauses.size() ); 431 for( auto & ocl : other.clauses ) { 432 clauses.emplace_back(); 433 clauses.back().target.function = ocl.target.function->clone(); 434 cloneAll( ocl.target.arguments, clauses.back().target.arguments ); 435 clauses.back().statement = ocl.statement->clone(); 436 clauses.back().condition = ocl.condition->clone(); 437 } 438 439 timeout.time = other.timeout.time ->clone(); 440 timeout.statement = other.timeout.statement->clone(); 441 timeout.condition = other.timeout.condition->clone(); 442 orelse .statement = other.orelse .statement->clone(); 443 orelse .condition = other.orelse .condition->clone(); 444 } 445 446 WaitForStmt::~WaitForStmt() { 447 for( auto & clause : clauses ) { 448 delete clause.target.function; 449 deleteAll( clause.target.arguments ); 450 delete clause.statement; 451 delete clause.condition; 452 } 453 454 delete timeout.time; 455 delete timeout.statement; 456 delete timeout.condition; 457 458 delete orelse.statement; 459 delete orelse.condition; 460 } 461 462 void WaitForStmt::print( std::ostream &os, int indent ) const { 463 os << "Waitfor Statement" << endl; 464 os << string( indent + 2, ' ' ) << "with block:" << endl; 465 os << string( indent + 4, ' ' ); 466 // block->print( os, indent + 4 ); 467 } 468 421 469 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {} 422 470 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {} -
src/SynTree/Statement.h
r0c6596f r1cb758f2 19 19 #include <list> // for list 20 20 #include <memory> // for allocator 21 #include <vector> // for vector 21 22 22 23 #include "BaseSyntaxNode.h" // for BaseSyntaxNode … … 392 393 }; 393 394 395 class WaitForStmt : public Statement { 396 public: 397 398 struct Target { 399 Expression * function; 400 std::list<Expression * > arguments; 401 }; 402 403 struct Clause { 404 Target target; 405 Statement * statement; 406 Expression * condition; 407 }; 408 409 WaitForStmt( std::list<Label> labels = noLabels ); 410 WaitForStmt( const WaitForStmt & ); 411 virtual ~WaitForStmt(); 412 413 std::vector<Clause> clauses; 414 415 struct { 416 Expression * time; 417 Statement * statement; 418 Expression * condition; 419 } timeout; 420 421 struct { 422 Statement * statement; 423 Expression * condition; 424 } orelse; 425 426 virtual WaitForStmt *clone() const { return new WaitForStmt( *this ); } 427 virtual void accept( Visitor &v ) { v.visit( this ); } 428 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 429 virtual void print( std::ostream &os, int indent = 0 ) const; 430 431 }; 432 394 433 395 434 // represents a declaration that occurs as part of a compound statement -
src/SynTree/SynTree.h
r0c6596f r1cb758f2 54 54 class CatchStmt; 55 55 class FinallyStmt; 56 class WaitForStmt; 56 57 class NullStmt; 57 58 class DeclStmt; -
src/SynTree/Visitor.cc
r0c6596f r1cb758f2 155 155 } 156 156 157 void Visitor::visit( WaitForStmt *waitforStmt ) { 158 for( auto & clause : waitforStmt->clauses ) { 159 maybeAccept( clause.target.function, *this ); 160 acceptAll( clause.target.arguments, *this ); 161 162 maybeAccept( clause.statement, *this ); 163 maybeAccept( clause.condition, *this ); 164 } 165 166 maybeAccept( waitforStmt->timeout.time, *this ); 167 maybeAccept( waitforStmt->timeout.statement, *this ); 168 maybeAccept( waitforStmt->timeout.condition, *this ); 169 maybeAccept( waitforStmt->orelse.statement, *this ); 170 maybeAccept( waitforStmt->orelse.condition, *this ); 171 } 172 157 173 void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) { 158 174 } -
src/SynTree/Visitor.h
r0c6596f r1cb758f2 51 51 virtual void visit( CatchStmt *catchStmt ); 52 52 virtual void visit( FinallyStmt *finallyStmt ); 53 virtual void visit( WaitForStmt *waitforStmt ); 53 54 virtual void visit( NullStmt *nullStmt ); 54 55 virtual void visit( DeclStmt *declStmt ); -
src/libcfa/concurrency/invoke.h
r0c6596f r1cb758f2 28 28 #define thread_local _Thread_local 29 29 30 typedef void (*fptr_t)(); 31 30 32 struct spinlock { 31 33 volatile int lock; … … 50 52 void append( struct __thread_queue_t *, struct thread_desc * ); 51 53 struct thread_desc * pop_head( struct __thread_queue_t * ); 54 struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** ); 52 55 53 56 void ?{}( struct __condition_stack_t & ); … … 87 90 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 88 91 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 89 }; 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 96 }; 90 97 91 98 struct thread_desc { 99 // Core threading fields 92 100 struct coroutine_desc cor; // coroutine body used to store context 93 101 struct monitor_desc mon; // monitor body used for mutual exclusion 102 103 // Link lists fields 94 104 struct thread_desc * next; // instrusive link field for threads 105 106 // Current status related to monitors 95 107 struct monitor_desc ** current_monitors; // currently held monitors 96 108 unsigned short current_monitor_count; // number of currently held monitors 97 }; 109 fptr_t current_monitor_func; // last function that acquired monitors 110 }; 98 111 99 112 #endif //_INVOKE_H_ -
src/libcfa/concurrency/kernel.c
r0c6596f r1cb758f2 322 322 void ScheduleThread( thread_desc * thrd ) { 323 323 // if( !thrd ) return; 324 assert( thrd );325 assert( thrd->cor.state != Halted );324 verify( thrd ); 325 verify( thrd->cor.state != Halted ); 326 326 327 327 verify( disable_preempt_count > 0 ); … … 366 366 367 367 void BlockInternal( thread_desc * thrd ) { 368 assert(thrd); 368 369 disable_interrupts(); 369 370 assert( thrd->cor.state != Halted ); … … 379 380 380 381 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 382 assert(thrd); 381 383 disable_interrupts(); 382 384 this_processor->finish.action_code = Release_Schedule; … … 666 668 } 667 669 670 thread_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 668 687 void ?{}( __condition_stack_t & this ) { 669 688 this.top = NULL; -
src/libcfa/concurrency/monitor
r0c6596f r1cb758f2 23 23 24 24 static inline void ?{}(monitor_desc & this) { 25 (this.lock){}; 25 26 this.owner = NULL; 27 (this.entry_queue){}; 28 (this.signal_stack){}; 26 29 this.recursion = 0; 30 this.acceptables = NULL; 31 this.acceptable_count = 0; 32 this.accepted_index = -1; 27 33 } 28 34 … … 32 38 monitor_desc ** prev_mntrs; 33 39 unsigned short prev_count; 40 fptr_t prev_func; 34 41 }; 35 42 … … 38 45 } 39 46 40 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count );47 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ); 41 48 void ^?{}( monitor_guard_t & this ); 42 49 … … 89 96 uintptr_t front( condition * this ); 90 97 98 //----------------------------------------------------------------------------- 99 // External scheduling 100 91 101 struct __acceptable_t { 92 void (*func)(void);102 fptr_t func; 93 103 unsigned short count; 94 monitor_desc * monitors[1];104 monitor_desc ** monitors; 95 105 }; 96 106 97 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void));107 int __accept_internal( unsigned short count, __acceptable_t * acceptables ); 98 108 99 109 // Local Variables: // -
src/libcfa/concurrency/monitor.c
r0c6596f r1cb758f2 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, monitor_desc ** group, int group_cnt, void (*func)() ); 27 28 28 29 static inline void lock_all( spinlock ** locks, unsigned short count ); … … 34 35 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ); 35 36 37 static inline void init ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ); 38 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ); 39 36 40 static inline thread_desc * check_condition( __condition_criterion_t * ); 37 41 static inline void brand_condition( condition * ); 38 42 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ); 39 43 44 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ); 45 46 //----------------------------------------------------------------------------- 47 // Useful defines 48 #define wait_ctx(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 49 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 50 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 51 init( count, monitors, &waiter, criteria ); /* Link everything together */ \ 52 53 #define wait_ctx_primed(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 54 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 55 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 56 init_push( count, monitors, &waiter, criteria ); /* Link everything together and push it to the AS-Stack */ \ 57 58 #define monitor_ctx( mons, cnt ) /* Define that create the necessary struct for internal/external scheduling operations */ \ 59 monitor_desc ** monitors = mons; /* Save the targeted monitors */ \ 60 unsigned short count = cnt; /* Save the count to a local variable */ \ 61 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 62 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 63 40 64 //----------------------------------------------------------------------------- 41 65 // Enter/Leave routines … … 43 67 44 68 extern "C" { 45 void __enter_monitor_desc( monitor_desc * this ) { 69 // Enter single monitor 70 static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) { 71 // Lock the monitor spinlock, lock_yield to reduce contention 46 72 lock_yield( &this->lock DEBUG_CTX2 ); 47 73 thread_desc * thrd = this_thread; 48 74 49 // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 50 75 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); 76 77 this->accepted_index = -1; 51 78 if( !this->owner ) { 52 // No one has the monitor, just take it79 // No one has the monitor, just take it 53 80 set_owner( this, thrd ); 81 82 LIB_DEBUG_PRINT_SAFE("Kernel : mon is free \n"); 54 83 } 55 84 else if( this->owner == thrd) { 56 // We already have the monitor, just not how many times we took it85 // We already have the monitor, just not how many times we took it 57 86 verify( this->recursion > 0 ); 58 87 this->recursion += 1; 88 89 LIB_DEBUG_PRINT_SAFE("Kernel : mon already owned \n"); 90 } 91 else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) { 92 // Some one was waiting for us, enter 93 set_owner( this, thrd ); 94 95 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts \n"); 59 96 } 60 97 else { 61 //Some one else has the monitor, wait in line for it 98 LIB_DEBUG_PRINT_SAFE("Kernel : blocking \n"); 99 100 // Some one else has the monitor, wait in line for it 62 101 append( &this->entry_queue, thrd ); 63 // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);64 102 BlockInternal( &this->lock ); 65 103 66 //BlockInternal will unlock spinlock, no need to unlock ourselves 104 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered mon %p\n", thrd, this); 105 106 // BlockInternal will unlock spinlock, no need to unlock ourselves 67 107 return; 68 108 } 69 109 110 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered mon %p\n", thrd, this); 111 112 // Release the lock and leave 70 113 unlock( &this->lock ); 71 114 return; 72 115 } 73 116 74 // leave pseudo code : 75 // TODO 117 // Leave single monitor 76 118 void __leave_monitor_desc( monitor_desc * this ) { 119 // Lock the monitor spinlock, lock_yield to reduce contention 77 120 lock_yield( &this->lock DEBUG_CTX2 ); 78 121 79 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);80 122 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion ); 81 123 82 // Leaving a recursion level, decrement the counter124 // Leaving a recursion level, decrement the counter 83 125 this->recursion -= 1; 84 126 85 // If we haven't left the last level of recursion86 // it means we don't need to do anything127 // If we haven't left the last level of recursion 128 // it means we don't need to do anything 87 129 if( this->recursion != 0) { 88 130 unlock( &this->lock ); … … 90 132 } 91 133 134 // Get the next thread, will be null on low contention monitor 92 135 thread_desc * new_owner = next_thread( this ); 93 136 94 // We can now let other threads in safely137 // We can now let other threads in safely 95 138 unlock( &this->lock ); 96 97 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);98 139 99 140 //We need to wake-up the thread … … 101 142 } 102 143 144 // Leave the thread monitor 145 // last routine called by a thread. 146 // Should never return 103 147 void __leave_thread_monitor( thread_desc * thrd ) { 104 148 monitor_desc * this = &thrd->mon; 149 150 // Lock the monitor now 105 151 lock_yield( &this->lock DEBUG_CTX2 ); 106 152 … … 111 157 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 112 158 113 // Leaving a recursion level, decrement the counter159 // Leaving a recursion level, decrement the counter 114 160 this->recursion -= 1; 115 161 116 //If we haven't left the last level of recursion 117 //it means we don't need to do anything 118 if( this->recursion != 0) { 119 unlock( &this->lock ); 120 return; 121 } 122 162 // If we haven't left the last level of recursion 163 // it must mean there is an error 164 if( this->recursion != 0) { abortf("Thread internal monitor has unbalanced recursion"); } 165 166 // Fetch the next thread, can be null 123 167 thread_desc * new_owner = next_thread( this ); 124 168 169 // Leave the thread, this will unlock the spinlock 170 // Use leave thread instead of BlockInternal which is 171 // specialized for this case and supports null new_owner 125 172 LeaveThread( &this->lock, new_owner ); 126 } 127 } 128 129 static inline void enter(monitor_desc ** monitors, int count) { 173 174 // Control flow should never reach here! 175 } 176 } 177 178 // Enter multiple monitor 179 // relies on the monitor array being sorted 180 static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) { 130 181 for(int i = 0; i < count; i++) { 131 __enter_monitor_desc( monitors[i] ); 132 } 133 } 134 182 __enter_monitor_desc( monitors[i], monitors, count, func ); 183 } 184 } 185 186 // Leave multiple monitor 187 // relies on the monitor array being sorted 135 188 static inline void leave(monitor_desc ** monitors, int count) { 136 189 for(int i = count - 1; i >= 0; i--) { … … 139 192 } 140 193 141 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count ) { 194 // Ctor for monitor guard 195 // Sorts monitors before entering 196 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) { 197 // Store current array 142 198 this.m = m; 143 199 this.count = count; 200 201 // Sort monitors based on address -> TODO use a sort specialized for small numbers 144 202 qsort(this.m, count); 145 enter( this.m, this.count ); 146 203 204 // Save previous thread context 147 205 this.prev_mntrs = this_thread->current_monitors; 148 206 this.prev_count = this_thread->current_monitor_count; 149 207 this.prev_func = this_thread->current_monitor_func; 208 209 // Update thread context (needed for conditions) 150 210 this_thread->current_monitors = m; 151 211 this_thread->current_monitor_count = count; 152 } 153 212 this_thread->current_monitor_func = func; 213 214 // Enter the monitors in order 215 enter( this.m, this.count, func ); 216 } 217 218 219 // Dtor for monitor guard 154 220 void ^?{}( monitor_guard_t & this ) { 221 // Leave the monitors in order 155 222 leave( this.m, this.count ); 156 223 224 // Restore thread context 157 225 this_thread->current_monitors = this.prev_mntrs; 158 226 this_thread->current_monitor_count = this.prev_count; 159 } 160 227 this_thread->current_monitor_func = this.prev_func; 228 } 229 230 //----------------------------------------------------------------------------- 231 // Internal scheduling types 161 232 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) { 162 233 this.waiting_thread = waiting_thread; … … 183 254 // Internal scheduling 184 255 void wait( condition * this, uintptr_t user_info = 0 ) { 185 // LIB_DEBUG_PRINT_SAFE("Waiting\n");186 187 256 brand_condition( this ); 188 257 189 // Check that everything is as expected258 // Check that everything is as expected 190 259 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 191 260 verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 192 261 verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count ); 193 262 194 unsigned short count = this->monitor_count; 195 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 196 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 197 198 // LIB_DEBUG_PRINT_SAFE("count %i\n", count); 199 200 __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info }; 201 202 __condition_criterion_t criteria[count]; 203 for(int i = 0; i < count; i++) { 204 (criteria[i]){ this->monitors[i], &waiter }; 205 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 206 } 207 208 waiter.criteria = criteria; 263 // Create storage for monitor context 264 monitor_ctx( this->monitors, this->monitor_count ); 265 266 // Create the node specific to this wait operation 267 wait_ctx( this_thread, user_info ); 268 269 // Append the current wait operation to the ones already queued on the condition 270 // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion 209 271 append( &this->blocked, &waiter ); 210 272 211 lock_all( this->monitors, locks, count ); 212 save_recursion( this->monitors, recursions, count ); 213 //DON'T unlock, ask the kernel to do it 214 215 //Find the next thread(s) to run 273 // Lock all monitors (aggregates the lock them as well) 274 lock_all( monitors, locks, count ); 275 276 // DON'T unlock, ask the kernel to do it 277 278 // Save monitor state 279 save_recursion( monitors, recursions, count ); 280 281 // Find the next thread(s) to run 216 282 unsigned short thread_count = 0; 217 283 thread_desc * threads[ count ]; … … 220 286 } 221 287 288 // Remove any duplicate threads 222 289 for( int i = 0; i < count; i++) { 223 thread_desc * new_owner = next_thread( this->monitors[i] );290 thread_desc * new_owner = next_thread( monitors[i] ); 224 291 thread_count = insert_unique( threads, thread_count, new_owner ); 225 292 } 226 227 // LIB_DEBUG_PRINT_SAFE("Will unblock: ");228 for(int i = 0; i < thread_count; i++) {229 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);230 }231 // LIB_DEBUG_PRINT_SAFE("\n");232 293 233 294 // Everything is ready to go to sleep … … 235 296 236 297 237 // WE WOKE UP238 239 240 // We are back, restore the owners and recursions298 // WE WOKE UP 299 300 301 // We are back, restore the owners and recursions 241 302 lock_all( locks, count ); 242 restore_recursion( this->monitors, recursions, count );303 restore_recursion( monitors, recursions, count ); 243 304 unlock_all( locks, count ); 244 305 } 245 306 246 307 bool signal( condition * this ) { 247 if( is_empty( this ) ) { 248 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 249 return false; 250 } 308 if( is_empty( this ) ) { return false; } 251 309 252 310 //Check that everything is as expected 253 311 verify( this->monitors ); 254 312 verify( this->monitor_count != 0 ); 255 256 unsigned short count = this->monitor_count;257 313 258 314 //Some more checking in debug … … 261 317 if ( this->monitor_count != this_thrd->current_monitor_count ) { 262 318 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count ); 263 } // if319 } 264 320 265 321 for(int i = 0; i < this->monitor_count; i++) { 266 322 if ( this->monitors[i] != this_thrd->current_monitors[i] ) { 267 323 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] ); 268 } // if324 } 269 325 } 270 326 ); 271 327 272 //Lock all the monitors 328 unsigned short count = this->monitor_count; 329 330 // Lock all monitors 273 331 lock_all( this->monitors, NULL, count ); 274 // LIB_DEBUG_PRINT_SAFE("Signalling");275 332 276 333 //Pop the head of the waiting queue … … 280 337 for(int i = 0; i < count; i++) { 281 338 __condition_criterion_t * crit = &node->criteria[i]; 282 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);283 339 assert( !crit->ready ); 284 340 push( &crit->target->signal_stack, crit ); 285 341 } 286 342 287 // LIB_DEBUG_PRINT_SAFE("\n");288 289 343 //Release 290 344 unlock_all( this->monitors, count ); … … 294 348 295 349 bool signal_block( condition * this ) { 296 if( !this->blocked.head ) { 297 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 298 return false; 299 } 350 if( !this->blocked.head ) { return false; } 300 351 301 352 //Check that everything is as expected … … 303 354 verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 304 355 305 unsigned short count = this->monitor_count; 306 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 307 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 308 309 lock_all( this->monitors, locks, count ); 310 311 //create creteria 312 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 }; 313 314 __condition_criterion_t criteria[count]; 315 for(int i = 0; i < count; i++) { 316 (criteria[i]){ this->monitors[i], &waiter }; 317 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 318 push( &criteria[i].target->signal_stack, &criteria[i] ); 319 } 320 321 waiter.criteria = criteria; 356 // Create storage for monitor context 357 monitor_ctx( this->monitors, this->monitor_count ); 358 359 // Lock all monitors (aggregates the locks them as well) 360 lock_all( monitors, locks, count ); 361 362 // Create the node specific to this wait operation 363 wait_ctx_primed( this_thread, 0 ) 322 364 323 365 //save contexts 324 save_recursion( this->monitors, recursions, count );366 save_recursion( monitors, recursions, count ); 325 367 326 368 //Find the thread to run 327 369 thread_desc * signallee = pop_head( &this->blocked )->waiting_thread; 328 370 for(int i = 0; i < count; i++) { 329 set_owner( this->monitors[i], signallee ); 330 } 331 332 LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" ); 371 set_owner( monitors[i], signallee ); 372 } 333 373 334 374 //Everything is ready to go to sleep … … 336 376 337 377 338 339 340 LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" ); 378 // WE WOKE UP 379 341 380 342 381 //We are back, restore the owners and recursions 343 382 lock_all( locks, count ); 344 restore_recursion( this->monitors, recursions, count );383 restore_recursion( monitors, recursions, count ); 345 384 unlock_all( locks, count ); 346 385 … … 348 387 } 349 388 389 // Access the user_info of the thread waiting at the front of the queue 350 390 uintptr_t front( condition * this ) { 351 391 verifyf( !is_empty(this), … … 358 398 //----------------------------------------------------------------------------- 359 399 // Internal scheduling 360 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 361 // thread_desc * this = this_thread; 362 363 // unsigned short count = this->current_monitor_count; 364 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 365 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 366 367 // lock_all( this->current_monitors, locks, count ); 368 369 370 371 372 373 // // // Everything is ready to go to sleep 374 // // BlockInternal( locks, count, threads, thread_count ); 375 376 377 // //WE WOKE UP 378 379 380 // //We are back, restore the owners and recursions 381 // lock_all( locks, count ); 382 // restore_recursion( this->monitors, recursions, count ); 383 // unlock_all( locks, count ); 400 int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) { 401 thread_desc * thrd = this_thread; 402 403 // Create storage for monitor context 404 monitor_ctx( acceptables->monitors, acceptables->count ); 405 406 // Lock all monitors (aggregates the lock them as well) 407 lock_all( monitors, locks, count ); 408 409 // Create the node specific to this wait operation 410 wait_ctx_primed( thrd, 0 ); 411 412 // Check if the entry queue 413 thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count ); 414 415 LIB_DEBUG_PRINT_SAFE("Owner(s) :"); 416 for(int i = 0; i < count; i++) { 417 LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner ); 418 } 419 LIB_DEBUG_PRINT_SAFE("\n"); 420 421 LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next); 422 423 if( !next ) { 424 // Update acceptables on the current monitors 425 for(int i = 0; i < count; i++) { 426 monitors[i]->acceptables = acceptables; 427 monitors[i]->acceptable_count = acc_count; 428 } 429 } 430 else { 431 for(int i = 0; i < count; i++) { 432 set_owner( monitors[i], next ); 433 } 434 } 435 436 437 save_recursion( monitors, recursions, count ); 438 439 440 // Everything is ready to go to sleep 441 BlockInternal( locks, count, &next, next ? 1 : 0 ); 442 443 444 //WE WOKE UP 445 446 447 //We are back, restore the owners and recursions 448 lock_all( locks, count ); 449 restore_recursion( monitors, recursions, count ); 450 int acc_idx = monitors[0]->accepted_index; 451 unlock_all( locks, count ); 452 453 return acc_idx; 384 454 } 385 455 … … 415 485 } 416 486 487 static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) { 488 __acceptable_t* accs = this->acceptables; // Optim 489 int acc_cnt = this->acceptable_count; 490 491 // Check if there are any acceptable functions 492 if( !accs ) return -1; 493 494 // If this isn't the first monitor to test this, there is no reason to repeat the test. 495 if( this != group[0] ) return group[0]->accepted_index; 496 497 // For all acceptable functions check if this is the current function. 498 OUT_LOOP: 499 for( int i = 0; i < acc_cnt; i++ ) { 500 __acceptable_t * acc = &accs[i]; 501 502 // if function matches, check the monitors 503 if( acc->func == func ) { 504 505 // If the group count is different then it can't be a match 506 if( acc->count != group_cnt ) return -1; 507 508 // Check that all the monitors match 509 for( int j = 0; j < group_cnt; j++ ) { 510 // If not a match, check next function 511 if( acc->monitors[j] != group[j] ) continue OUT_LOOP; 512 } 513 514 // It's a complete match, accept the call 515 return i; 516 } 517 } 518 519 // No function matched 520 return -1; 521 } 522 523 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) { 524 for(int i = 0; i < count; i++) { 525 (criteria[i]){ monitors[i], waiter }; 526 } 527 528 waiter->criteria = criteria; 529 } 530 531 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) { 532 for(int i = 0; i < count; i++) { 533 (criteria[i]){ monitors[i], waiter }; 534 push( &criteria[i].target->signal_stack, &criteria[i] ); 535 } 536 537 waiter->criteria = criteria; 538 } 539 417 540 static inline void lock_all( spinlock ** locks, unsigned short count ) { 418 541 for( int i = 0; i < count; i++ ) { … … 505 628 } 506 629 630 631 static inline bool match( __acceptable_t * acc, thread_desc * thrd ) { 632 verify( thrd ); 633 verify( acc ); 634 if( acc->func != thrd->current_monitor_func ) return false; 635 636 return true; 637 } 638 639 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) { 640 641 __thread_queue_t * entry_queue = &monitors[0]->entry_queue; 642 643 // For each thread in the entry-queue 644 for( thread_desc ** thrd_it = &entry_queue->head; 645 *thrd_it; 646 thrd_it = &(*thrd_it)->next) 647 { 648 // For each acceptable check if it matches 649 __acceptable_t * acc_end = acceptables + acc_count; 650 for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) { 651 // Check if we have a match 652 if( match( acc_it, *thrd_it ) ) { 653 654 // If we have a match return it 655 // after removeing it from the entry queue 656 return remove( entry_queue, thrd_it ); 657 } 658 } 659 } 660 661 return NULL; 662 } 507 663 void ?{}( __condition_blocked_queue_t & this ) { 508 664 this.head = NULL; -
src/libcfa/concurrency/preemption.c
r0c6596f r1cb758f2 332 332 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 333 333 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 ); 335 335 // Switch on the code (a.k.a. the sender) to 336 336 switch( info.si_code ) … … 340 340 case SI_TIMER: 341 341 case SI_KERNEL: 342 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");342 // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 343 343 lock( &event_kernel->lock DEBUG_CTX2 ); 344 344 tick_preemption(); -
src/tests/gmp.c
r0c6596f r1cb758f2 10 10 // Created On : Tue Apr 19 08:55:51 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 24 09:33:26201713 // Update Count : 54 312 // Last Modified On : Fri Aug 25 12:50:01 2017 13 // Update Count : 544 14 14 // 15 16 // NOTE: UBUNTU DOES NOT SUPPORT GMP MULTILIB, SO ONLY 64-BIT GMP IS TESTED. 15 17 16 18 #include <gmp> -
src/tests/preempt_longrun/stack.c
r0c6596f r1cb758f2 15 15 16 16 void main(worker_t * this) { 17 volatile long p = 5_021_609ul;18 volatile long a = 326_417ul;19 volatile long n = 1l;20 for (volatile long i = 0; i < p; i++) {17 volatile long long p = 5_021_609ul; 18 volatile long long a = 326_417ul; 19 volatile long long n = 1l; 20 for (volatile long long i = 0; i < p; i++) { 21 21 n *= a; 22 22 n %= p; -
src/tests/sched-int-disjoint.c
r0c6596f r1cb758f2 3 3 #include <monitor> 4 4 #include <thread> 5 6 #include <time.h> 5 7 6 8 static const unsigned long N = 10_000ul; … … 107 109 // Main loop 108 110 int main(int argc, char* argv[]) { 111 rand48seed( time( NULL ) ); 109 112 all_done = false; 110 113 processor p; -
src/tests/sched-int-wait.c
r0c6596f r1cb758f2 5 5 #include <thread> 6 6 7 static const unsigned long N = 10_000ul; 7 #include <time.h> 8 9 static const unsigned long N = 2_500ul; 8 10 9 11 #ifndef PREEMPTION_RATE … … 119 121 // Main 120 122 int main(int argc, char* argv[]) { 123 rand48seed( time( NULL ) ); 121 124 waiter_left = 4; 122 125 processor p[2]; -
src/tests/switch.c
r0c6596f r1cb758f2 10 10 // Created On : Tue Jul 12 06:50:22 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 4 11:44:29 201613 // Update Count : 3 112 // Last Modified On : Sat Aug 26 10:14:21 2017 13 // Update Count : 33 14 14 // 15 15 16 16 int f( int i ) { return i; } 17 17 18 int main( ) {18 int main( void ) { 19 19 int i = 0; 20 20 switch ( i ) case 3 : i = 1; … … 100 100 j = 5; 101 101 } // choose 102 } 102 } // main 103 103 104 104 // Local Variables: //
Note: See TracChangeset
for help on using the changeset viewer.