Changeset 1cb758f2


Ignore:
Timestamp:
Aug 27, 2017, 11:26:26 AM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
111a8af, 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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Location:
src
Files:
3 added
1 deleted
21 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r0c6596f r1cb758f2  
    201201                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
    202202                void validate( DeclarationWithType * );
    203                 void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);
     203                void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    204204
    205205                static void implement( std::list< Declaration * > & translationUnit ) {
     
    211211                StructDecl* monitor_decl = nullptr;
    212212                StructDecl* guard_decl = nullptr;
     213
     214                static std::unique_ptr< Type > generic_func;
    213215        };
     216
     217        std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >(
     218                new FunctionType(
     219                        noQualifiers,
     220                        true
     221                )
     222        );
    214223
    215224        //-----------------------------------------------------------------------------
     
    395404        // Mutex keyword implementation
    396405        //=============================================================================================
     406
    397407        void MutexKeyword::visit(FunctionDecl* decl) {
    398408                Visitor::visit(decl);
     
    411421                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    412422
    413                 addStatments( body, mutexArgs );
     423                addStatments( decl, body, mutexArgs );
    414424        }
    415425
     
    458468        }
    459469
    460         void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     470        void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    461471                ObjectDecl * monitors = new ObjectDecl(
    462472                        "__monitors",
     
    489499                );
    490500
     501                assert(generic_func);
     502
    491503                //in reverse order :
    492                 // monitor_guard_t __guard = { __monitors, # };
     504                // monitor_guard_t __guard = { __monitors, #, func };
    493505                body->push_front(
    494506                        new DeclStmt( noLabels, new ObjectDecl(
     
    504516                                        {
    505517                                                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() ) )
    507520                                        },
    508521                                        noDesignators,
  • src/Parser/ParseNode.h

    r0c6596f r1cb758f2  
    414414Statement * build_compound( StatementNode * first );
    415415Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
     416WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
     417WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
     418WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
     419WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
    416420
    417421//##############################################################################
  • src/Parser/StatementNode.cc

    r0c6596f r1cb758f2  
    9393                elseb = branches.front();
    9494        } // if
    95        
     95
    9696        std::list< Statement * > init;
    9797        if ( ctl->init != 0 ) {
     
    207207}
    208208
     209WaitForStmt * 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
     226WaitForStmt * 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
     242WaitForStmt * 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
     258WaitForStmt * 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
    209277Statement *build_compound( StatementNode *first ) {
    210278        CompoundStmt *cs = new CompoundStmt( noLabels );
  • src/Parser/parser.yy

    r0c6596f r1cb758f2  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 23 21:08:08 2017
    13 // Update Count     : 2704
     12// Last Modified On : Sat Aug 26 17:50:19 2017
     13// Update Count     : 2712
    1414//
    1515
     
    9797        DeclarationNode::TypeClass tclass;
    9898        StatementNode * sn;
     99        WaitForStmt * wfs;
    99100        ConstantExpr * constant;
    100101        IfCtl * ifctl;
     
    119120%token RESTRICT                                                                                 // C99
    120121%token ATOMIC                                                                                   // C11
    121 %token FORALL MUTEX VIRTUAL                                             // CFA
     122%token FORALL MUTEX VIRTUAL                                                             // CFA
    122123%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    123124%token BOOL COMPLEX IMAGINARY                                                   // C99
     
    189190
    190191// 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
    199196%type<en> case_value
    200197%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
    203203%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
    204207
    205208// declarations
     
    773776          push push
    774777          local_label_declaration_opt                                           // GCC, local labels
    775           block_item_list                                                                       // C99, intermix declarations and statements
     778          statement_decl_list                                                           // C99, intermix declarations and statements
    776779          pop '}'
    777780                { $$ = new StatementNode( build_compound( $5 ) ); }
    778781        ;
    779782
    780 block_item_list:                                                                                // C99
    781         block_item
    782         | block_item_list push block_item
     783statement_decl_list:                                                                    // C99
     784        statement_decl
     785        | statement_decl_list push statement_decl
    783786                { if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } }
    784787        ;
    785788
    786 block_item:
     789statement_decl:
    787790        declaration                                                                                     // CFA, new & old style declarations
    788791                { $$ = new StatementNode( $1 ); }
     
    802805        ;
    803806
    804 statement_list:
     807statement_list_nodecl:
    805808        statement
    806         | statement_list statement
     809        | statement_list_nodecl statement
    807810                { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
    808811        ;
     
    814817
    815818selection_statement:
    816         IF '(' push if_control_expression ')' statement                         %prec THEN
     819        IF '(' push if_control_expression ')' statement         %prec THEN
    817820                // explicitly deal with the shift/reduce conflict on if/else
    818821                { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); }
     
    889892
    890893switch_clause_list:                                                                             // CFA
    891         case_label_list statement_list
     894        case_label_list statement_list_nodecl
    892895                { $$ = $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
    894897                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
    895898        ;
     
    904907        case_label_list fall_through
    905908                { $$ = $1->append_last_case( $2 ); }
    906         | case_label_list statement_list fall_through_opt
     909        | case_label_list statement_list_nodecl fall_through_opt
    907910                { $$ = $1->append_last_case( new StatementNode( build_compound( (StatementNode *)$2->set_last( $3 ) ) ) ); }
    908911        | choose_clause_list case_label_list fall_through
    909912                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( $3 ))); }
    910         | choose_clause_list case_label_list statement_list fall_through_opt
     913        | choose_clause_list case_label_list statement_list_nodecl fall_through_opt
    911914                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( (StatementNode *)$3->set_last( $4 ) ) ) ) ) ); }
    912915        ;
     
    977980        ;
    978981
     982when_clause:
     983        WHEN '(' comma_expression ')'
     984                { $$ = $3; }
     985        ;
     986
    979987when_clause_opt:
    980988        // empty
    981                 { $$ = nullptr; }                                                               // FIX ME
    982         | WHEN '(' comma_expression ')'
    983                 { $$ = nullptr; }                                                               // FIX ME
     989                { $$ = nullptr; }
     990        | when_clause
    984991        ;
    985992
    986993waitfor:
    987994        WAITFOR '(' identifier ')'
    988                 { $$ = nullptr; }                                                               // FIX ME
     995                {
     996                        $$ = new ExpressionNode( new NameExpr( *$3 ) );
     997                        delete $3;
     998                }
    989999        | WAITFOR '(' identifier ',' argument_expression_list ')'
    990                 { $$ = nullptr; }                                                               // FIX ME
     1000                {
     1001                        $$ = new ExpressionNode( new NameExpr( *$3 ) );
     1002                        $$->set_last( $5 );
     1003                        delete $3;
     1004                }
    9911005        ;
    9921006
    9931007timeout:
    9941008        TIMEOUT '(' comma_expression ')'
    995                 { $$ = nullptr; }                                                               // FIX ME
     1009                { $$ = $3; }
    9961010        ;
    9971011
    9981012waitfor_clause:
    999         when_clause_opt waitfor statement %prec THEN
    1000                 { $$ = nullptr; }                                                               // FIX ME
     1013        when_clause_opt waitfor statement                                       %prec THEN
     1014                { $$ = build_waitfor( $2, $3, $1 ); }
    10011015        | when_clause_opt waitfor statement WOR waitfor_clause
    1002                 { $$ = nullptr; }                                                               // FIX ME
    1003         | when_clause_opt timeout statement %prec THEN
    1004                 { $$ = nullptr; }                                                               // FIX ME
     1016                { $$ = build_waitfor( $2, $3, $1, $5 ); }
     1017        | when_clause_opt timeout statement                                     %prec THEN
     1018                { $$ = build_waitfor_timeout( $2, $3, $1 ); }
    10051019        | 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 ); }
    10091024        ;
    10101025
    10111026waitfor_statement:
    1012         when_clause_opt waitfor statement %prec THEN
    1013                 { $$ = nullptr; }                                                               // FIX ME
     1027        when_clause_opt waitfor statement                                       %prec THEN
     1028                { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); }
    10141029        | when_clause_opt waitfor statement WOR waitfor_clause
    1015                 { $$ = nullptr; }                                                               // FIX ME
     1030                { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); }
    10161031        ;
    10171032
  • src/SynTree/Mutator.cc

    r0c6596f r1cb758f2  
    3232Mutator::~Mutator() {}
    3333
    34 DeclarationWithType *Mutator::mutate( ObjectDecl *objectDecl ) {
     34DeclarationWithType * Mutator::mutate( ObjectDecl *objectDecl ) {
    3535        objectDecl->set_type( maybeMutate( objectDecl->get_type(), *this ) );
    3636        objectDecl->set_init( maybeMutate( objectDecl->get_init(), *this ) );
     
    3939}
    4040
    41 DeclarationWithType *Mutator::mutate( FunctionDecl *functionDecl ) {
     41DeclarationWithType * Mutator::mutate( FunctionDecl *functionDecl ) {
    4242        functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    4343        functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     
    4545}
    4646
    47 Declaration *Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {
     47Declaration * Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {
    4848        mutateAll( aggregateDecl->get_parameters(), *this );
    4949        mutateAll( aggregateDecl->get_members(), *this );
     
    5151}
    5252
    53 Declaration *Mutator::mutate( StructDecl *aggregateDecl ) {
     53Declaration * Mutator::mutate( StructDecl *aggregateDecl ) {
    5454        handleAggregateDecl( aggregateDecl );
    5555        return aggregateDecl;
    5656}
    5757
    58 Declaration *Mutator::mutate( UnionDecl *aggregateDecl ) {
     58Declaration * Mutator::mutate( UnionDecl *aggregateDecl ) {
    5959        handleAggregateDecl( aggregateDecl );
    6060        return aggregateDecl;
    6161}
    6262
    63 Declaration *Mutator::mutate( EnumDecl *aggregateDecl ) {
     63Declaration * Mutator::mutate( EnumDecl *aggregateDecl ) {
    6464        handleAggregateDecl( aggregateDecl );
    6565        return aggregateDecl;
    6666}
    6767
    68 Declaration *Mutator::mutate( TraitDecl *aggregateDecl ) {
     68Declaration * Mutator::mutate( TraitDecl *aggregateDecl ) {
    6969        handleAggregateDecl( aggregateDecl );
    7070        return aggregateDecl;
    7171}
    7272
    73 Declaration *Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {
     73Declaration * Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {
    7474        mutateAll( typeDecl->get_parameters(), *this );
    7575        mutateAll( typeDecl->get_assertions(), *this );
     
    7878}
    7979
    80 TypeDecl *Mutator::mutate( TypeDecl *typeDecl ) {
     80TypeDecl * Mutator::mutate( TypeDecl *typeDecl ) {
    8181        handleNamedTypeDecl( typeDecl );
    8282        typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) );
     
    8484}
    8585
    86 Declaration *Mutator::mutate( TypedefDecl *typeDecl ) {
     86Declaration * Mutator::mutate( TypedefDecl *typeDecl ) {
    8787        handleNamedTypeDecl( typeDecl );
    8888        return typeDecl;
    8989}
    9090
    91 AsmDecl *Mutator::mutate( AsmDecl *asmDecl ) {
     91AsmDecl * Mutator::mutate( AsmDecl *asmDecl ) {
    9292        asmDecl->set_stmt( maybeMutate( asmDecl->get_stmt(), *this ) );
    9393        return asmDecl;
     
    9595
    9696
    97 CompoundStmt *Mutator::mutate( CompoundStmt *compoundStmt ) {
     97CompoundStmt * Mutator::mutate( CompoundStmt *compoundStmt ) {
    9898        mutateAll( compoundStmt->get_kids(), *this );
    9999        return compoundStmt;
    100100}
    101101
    102 Statement *Mutator::mutate( ExprStmt *exprStmt ) {
     102Statement * Mutator::mutate( ExprStmt *exprStmt ) {
    103103        exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
    104104        return exprStmt;
    105105}
    106106
    107 Statement *Mutator::mutate( AsmStmt *asmStmt ) {
     107Statement * Mutator::mutate( AsmStmt *asmStmt ) {
    108108        asmStmt->set_instruction( maybeMutate( asmStmt->get_instruction(), *this ) );
    109109        mutateAll( asmStmt->get_output(), *this );
     
    113113}
    114114
    115 Statement *Mutator::mutate( IfStmt *ifStmt ) {
     115Statement * Mutator::mutate( IfStmt *ifStmt ) {
    116116        mutateAll( ifStmt->get_initialization(), *this );
    117117        ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) );
     
    121121}
    122122
    123 Statement *Mutator::mutate( WhileStmt *whileStmt ) {
     123Statement * Mutator::mutate( WhileStmt *whileStmt ) {
    124124        whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) );
    125125        whileStmt->set_body( maybeMutate( whileStmt->get_body(), *this ) );
     
    127127}
    128128
    129 Statement *Mutator::mutate( ForStmt *forStmt ) {
     129Statement * Mutator::mutate( ForStmt *forStmt ) {
    130130        mutateAll( forStmt->get_initialization(), *this );
    131131        forStmt->set_condition( maybeMutate( forStmt->get_condition(), *this ) );
     
    135135}
    136136
    137 Statement *Mutator::mutate( SwitchStmt *switchStmt ) {
     137Statement * Mutator::mutate( SwitchStmt *switchStmt ) {
    138138        switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
    139139        mutateAll( switchStmt->get_statements(), *this );
     
    141141}
    142142
    143 Statement *Mutator::mutate( CaseStmt *caseStmt ) {
     143Statement * Mutator::mutate( CaseStmt *caseStmt ) {
    144144        caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
    145145        mutateAll (caseStmt->get_statements(), *this );
     
    148148}
    149149
    150 Statement *Mutator::mutate( BranchStmt *branchStmt ) {
     150Statement * Mutator::mutate( BranchStmt *branchStmt ) {
    151151        return branchStmt;
    152152}
    153153
    154 Statement *Mutator::mutate( ReturnStmt *returnStmt ) {
     154Statement * Mutator::mutate( ReturnStmt *returnStmt ) {
    155155        returnStmt->set_expr( maybeMutate( returnStmt->get_expr(), *this ) );
    156156        return returnStmt;
    157157}
    158158
    159 Statement *Mutator::mutate( ThrowStmt *throwStmt ) {
     159Statement * Mutator::mutate( ThrowStmt *throwStmt ) {
    160160        throwStmt->set_expr( maybeMutate( throwStmt->get_expr(), *this ) );
    161161        throwStmt->set_target( maybeMutate( throwStmt->get_target(), *this ) );
     
    163163}
    164164
    165 Statement *Mutator::mutate( TryStmt *tryStmt ) {
     165Statement * Mutator::mutate( TryStmt *tryStmt ) {
    166166        tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
    167167        mutateAll( tryStmt->get_catchers(), *this );
     
    170170}
    171171
    172 Statement *Mutator::mutate( CatchStmt *catchStmt ) {
     172Statement * Mutator::mutate( CatchStmt *catchStmt ) {
    173173        catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
    174174        catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
     
    177177}
    178178
    179 Statement *Mutator::mutate( FinallyStmt *finalStmt ) {
     179Statement * Mutator::mutate( FinallyStmt *finalStmt ) {
    180180        finalStmt->set_block( maybeMutate( finalStmt->get_block(), *this ) );
    181181        return finalStmt;
    182182}
    183183
    184 NullStmt *Mutator::mutate( NullStmt *nullStmt ) {
     184Statement * 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
     202NullStmt * Mutator::mutate( NullStmt *nullStmt ) {
    185203        return nullStmt;
    186204}
    187205
    188 Statement *Mutator::mutate( DeclStmt *declStmt ) {
     206Statement * Mutator::mutate( DeclStmt *declStmt ) {
    189207        declStmt->set_decl( maybeMutate( declStmt->get_decl(), *this ) );
    190208        return declStmt;
    191209}
    192210
    193 Statement *Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
     211Statement * Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
    194212        impCtorDtorStmt->set_callStmt( maybeMutate( impCtorDtorStmt->get_callStmt(), *this ) );
    195213        return impCtorDtorStmt;
     
    197215
    198216
    199 Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
     217Expression * Mutator::mutate( ApplicationExpr *applicationExpr ) {
    200218        applicationExpr->set_env( maybeMutate( applicationExpr->get_env(), *this ) );
    201219        applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) );
     
    205223}
    206224
    207 Expression *Mutator::mutate( UntypedExpr *untypedExpr ) {
     225Expression * Mutator::mutate( UntypedExpr *untypedExpr ) {
    208226        untypedExpr->set_env( maybeMutate( untypedExpr->get_env(), *this ) );
    209227        untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) );
     
    212230}
    213231
    214 Expression *Mutator::mutate( NameExpr *nameExpr ) {
     232Expression * Mutator::mutate( NameExpr *nameExpr ) {
    215233        nameExpr->set_env( maybeMutate( nameExpr->get_env(), *this ) );
    216234        nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) );
     
    218236}
    219237
    220 Expression *Mutator::mutate( AddressExpr *addressExpr ) {
     238Expression * Mutator::mutate( AddressExpr *addressExpr ) {
    221239        addressExpr->set_env( maybeMutate( addressExpr->get_env(), *this ) );
    222240        addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) );
     
    225243}
    226244
    227 Expression *Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
     245Expression * Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
    228246        labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
    229247        labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
     
    232250}
    233251
    234 Expression *Mutator::mutate( CastExpr *castExpr ) {
     252Expression * Mutator::mutate( CastExpr *castExpr ) {
    235253        castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
    236254        castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
     
    239257}
    240258
    241 Expression *Mutator::mutate( VirtualCastExpr *castExpr ) {
     259Expression * Mutator::mutate( VirtualCastExpr *castExpr ) {
    242260        castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
    243261        castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
     
    246264}
    247265
    248 Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) {
     266Expression * Mutator::mutate( UntypedMemberExpr *memberExpr ) {
    249267        memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
    250268        memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
     
    254272}
    255273
    256 Expression *Mutator::mutate( MemberExpr *memberExpr ) {
     274Expression * Mutator::mutate( MemberExpr *memberExpr ) {
    257275        memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
    258276        memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
     
    261279}
    262280
    263 Expression *Mutator::mutate( VariableExpr *variableExpr ) {
     281Expression * Mutator::mutate( VariableExpr *variableExpr ) {
    264282        variableExpr->set_env( maybeMutate( variableExpr->get_env(), *this ) );
    265283        variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) );
     
    267285}
    268286
    269 Expression *Mutator::mutate( ConstantExpr *constantExpr ) {
     287Expression * Mutator::mutate( ConstantExpr *constantExpr ) {
    270288        constantExpr->set_env( maybeMutate( constantExpr->get_env(), *this ) );
    271289        constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) );
     
    274292}
    275293
    276 Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) {
     294Expression * Mutator::mutate( SizeofExpr *sizeofExpr ) {
    277295        sizeofExpr->set_env( maybeMutate( sizeofExpr->get_env(), *this ) );
    278296        sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) );
     
    285303}
    286304
    287 Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
     305Expression * Mutator::mutate( AlignofExpr *alignofExpr ) {
    288306        alignofExpr->set_env( maybeMutate( alignofExpr->get_env(), *this ) );
    289307        alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) );
     
    296314}
    297315
    298 Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
     316Expression * Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
    299317        offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) );
    300318        offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
     
    303321}
    304322
    305 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
     323Expression * Mutator::mutate( OffsetofExpr *offsetofExpr ) {
    306324        offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) );
    307325        offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
     
    311329}
    312330
    313 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
     331Expression * Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
    314332        offsetPackExpr->set_env( maybeMutate( offsetPackExpr->get_env(), *this ) );
    315333        offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) );
     
    318336}
    319337
    320 Expression *Mutator::mutate( AttrExpr *attrExpr ) {
     338Expression * Mutator::mutate( AttrExpr *attrExpr ) {
    321339        attrExpr->set_env( maybeMutate( attrExpr->get_env(), *this ) );
    322340        attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) );
     
    329347}
    330348
    331 Expression *Mutator::mutate( LogicalExpr *logicalExpr ) {
     349Expression * Mutator::mutate( LogicalExpr *logicalExpr ) {
    332350        logicalExpr->set_env( maybeMutate( logicalExpr->get_env(), *this ) );
    333351        logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) );
     
    337355}
    338356
    339 Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) {
     357Expression * Mutator::mutate( ConditionalExpr *conditionalExpr ) {
    340358        conditionalExpr->set_env( maybeMutate( conditionalExpr->get_env(), *this ) );
    341359        conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) );
     
    346364}
    347365
    348 Expression *Mutator::mutate( CommaExpr *commaExpr ) {
     366Expression * Mutator::mutate( CommaExpr *commaExpr ) {
    349367        commaExpr->set_env( maybeMutate( commaExpr->get_env(), *this ) );
    350368        commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) );
     
    354372}
    355373
    356 Expression *Mutator::mutate( TypeExpr *typeExpr ) {
     374Expression * Mutator::mutate( TypeExpr *typeExpr ) {
    357375        typeExpr->set_env( maybeMutate( typeExpr->get_env(), *this ) );
    358376        typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) );
     
    361379}
    362380
    363 Expression *Mutator::mutate( AsmExpr *asmExpr ) {
     381Expression * Mutator::mutate( AsmExpr *asmExpr ) {
    364382        asmExpr->set_env( maybeMutate( asmExpr->get_env(), *this ) );
    365383        asmExpr->set_inout( maybeMutate( asmExpr->get_inout(), *this ) );
     
    386404}
    387405
    388 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
     406Expression * Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
    389407        compLitExpr->set_env( maybeMutate( compLitExpr->get_env(), *this ) );
    390408        compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) );
     
    393411}
    394412
    395 Expression *Mutator::mutate( RangeExpr *rangeExpr ) {
     413Expression * Mutator::mutate( RangeExpr *rangeExpr ) {
    396414        rangeExpr->set_env( maybeMutate( rangeExpr->get_env(), *this ) );
    397415        rangeExpr->set_low( maybeMutate( rangeExpr->get_low(), *this ) );
     
    400418}
    401419
    402 Expression *Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
     420Expression * Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
    403421        tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    404422        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
     
    407425}
    408426
    409 Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
     427Expression * Mutator::mutate( TupleExpr *tupleExpr ) {
    410428        tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    411429        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
     
    414432}
    415433
    416 Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
     434Expression * Mutator::mutate( TupleIndexExpr *tupleExpr ) {
    417435        tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
    418436        tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
     
    421439}
    422440
    423 Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
     441Expression * Mutator::mutate( TupleAssignExpr *assignExpr ) {
    424442        assignExpr->set_env( maybeMutate( assignExpr->get_env(), *this ) );
    425443        assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
     
    428446}
    429447
    430 Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
     448Expression * Mutator::mutate( StmtExpr *stmtExpr ) {
    431449        stmtExpr->set_env( maybeMutate( stmtExpr->get_env(), *this ) );
    432450        stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
     
    437455}
    438456
    439 Expression *Mutator::mutate( UniqueExpr *uniqueExpr ) {
     457Expression * Mutator::mutate( UniqueExpr *uniqueExpr ) {
    440458        uniqueExpr->set_env( maybeMutate( uniqueExpr->get_env(), *this ) );
    441459        uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) );
     
    444462}
    445463
    446 Expression *Mutator::mutate( UntypedInitExpr * initExpr ) {
     464Expression * Mutator::mutate( UntypedInitExpr * initExpr ) {
    447465        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
    448466        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     
    452470}
    453471
    454 Expression *Mutator::mutate( InitExpr * initExpr ) {
     472Expression * Mutator::mutate( InitExpr * initExpr ) {
    455473        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
    456474        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     
    461479
    462480
    463 Type *Mutator::mutate( VoidType *voidType ) {
     481Type * Mutator::mutate( VoidType *voidType ) {
    464482        mutateAll( voidType->get_forall(), *this );
    465483        return voidType;
    466484}
    467485
    468 Type *Mutator::mutate( BasicType *basicType ) {
     486Type * Mutator::mutate( BasicType *basicType ) {
    469487        mutateAll( basicType->get_forall(), *this );
    470488        return basicType;
    471489}
    472490
    473 Type *Mutator::mutate( PointerType *pointerType ) {
     491Type * Mutator::mutate( PointerType *pointerType ) {
    474492        mutateAll( pointerType->get_forall(), *this );
    475493        pointerType->set_base( maybeMutate( pointerType->get_base(), *this ) );
     
    477495}
    478496
    479 Type *Mutator::mutate( ArrayType *arrayType ) {
     497Type * Mutator::mutate( ArrayType *arrayType ) {
    480498        mutateAll( arrayType->get_forall(), *this );
    481499        arrayType->set_dimension( maybeMutate( arrayType->get_dimension(), *this ) );
     
    484502}
    485503
    486 Type *Mutator::mutate( ReferenceType *refType ) {
     504Type * Mutator::mutate( ReferenceType * refType ) {
    487505        mutateAll( refType->get_forall(), *this );
    488506        refType->set_base( maybeMutate( refType->get_base(), *this ) );
     
    490508}
    491509
    492 Type *Mutator::mutate( FunctionType *functionType ) {
     510Type * Mutator::mutate( FunctionType * functionType ) {
    493511        mutateAll( functionType->get_forall(), *this );
    494512        mutateAll( functionType->get_returnVals(), *this );
     
    497515}
    498516
    499 Type *Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {
     517Type * Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {
    500518        mutateAll( aggregateUseType->get_forall(), *this );
    501519        mutateAll( aggregateUseType->get_parameters(), *this );
     
    503521}
    504522
    505 Type *Mutator::mutate( StructInstType *aggregateUseType ) {
     523Type * Mutator::mutate( StructInstType *aggregateUseType ) {
    506524        handleReferenceToType( aggregateUseType );
    507525        return aggregateUseType;
    508526}
    509527
    510 Type *Mutator::mutate( UnionInstType *aggregateUseType ) {
     528Type * Mutator::mutate( UnionInstType *aggregateUseType ) {
    511529        handleReferenceToType( aggregateUseType );
    512530        return aggregateUseType;
    513531}
    514532
    515 Type *Mutator::mutate( EnumInstType *aggregateUseType ) {
     533Type * Mutator::mutate( EnumInstType *aggregateUseType ) {
    516534        handleReferenceToType( aggregateUseType );
    517535        return aggregateUseType;
    518536}
    519537
    520 Type *Mutator::mutate( TraitInstType *aggregateUseType ) {
     538Type * Mutator::mutate( TraitInstType *aggregateUseType ) {
    521539        handleReferenceToType( aggregateUseType );
    522540        mutateAll( aggregateUseType->get_members(), *this );
     
    524542}
    525543
    526 Type *Mutator::mutate( TypeInstType *aggregateUseType ) {
     544Type * Mutator::mutate( TypeInstType *aggregateUseType ) {
    527545        handleReferenceToType( aggregateUseType );
    528546        return aggregateUseType;
    529547}
    530548
    531 Type *Mutator::mutate( TupleType *tupleType ) {
     549Type * Mutator::mutate( TupleType *tupleType ) {
    532550        mutateAll( tupleType->get_forall(), *this );
    533551        mutateAll( tupleType->get_types(), *this );
     
    536554}
    537555
    538 Type *Mutator::mutate( TypeofType *typeofType ) {
     556Type * Mutator::mutate( TypeofType *typeofType ) {
    539557        assert( typeofType->get_expr() );
    540558        typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) );
     
    542560}
    543561
    544 Type *Mutator::mutate( AttrType *attrType ) {
     562Type * Mutator::mutate( AttrType *attrType ) {
    545563        if ( attrType->get_isType() ) {
    546564                assert( attrType->get_type() );
     
    553571}
    554572
    555 Type *Mutator::mutate( VarArgsType *varArgsType ) {
     573Type * Mutator::mutate( VarArgsType *varArgsType ) {
    556574        mutateAll( varArgsType->get_forall(), *this );
    557575        return varArgsType;
    558576}
    559577
    560 Type *Mutator::mutate( ZeroType *zeroType ) {
     578Type * Mutator::mutate( ZeroType *zeroType ) {
    561579        mutateAll( zeroType->get_forall(), *this );
    562580        return zeroType;
    563581}
    564582
    565 Type *Mutator::mutate( OneType *oneType ) {
     583Type * Mutator::mutate( OneType *oneType ) {
    566584        mutateAll( oneType->get_forall(), *this );
    567585        return oneType;
     
    569587
    570588
    571 Designation *Mutator::mutate( Designation * designation ) {
     589Designation * Mutator::mutate( Designation * designation ) {
    572590        mutateAll( designation->get_designators(), *this );
    573591        return designation;
    574592}
    575593
    576 Initializer *Mutator::mutate( SingleInit *singleInit ) {
     594Initializer * Mutator::mutate( SingleInit *singleInit ) {
    577595        singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
    578596        return singleInit;
    579597}
    580598
    581 Initializer *Mutator::mutate( ListInit *listInit ) {
     599Initializer * Mutator::mutate( ListInit *listInit ) {
    582600        mutateAll( listInit->get_designations(), *this );
    583601        mutateAll( listInit->get_initializers(), *this );
     
    585603}
    586604
    587 Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
     605Initializer * Mutator::mutate( ConstructorInit *ctorInit ) {
    588606        ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
    589607        ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) );
     
    593611
    594612
    595 Subrange *Mutator::mutate( Subrange *subrange ) {
     613Subrange * Mutator::mutate( Subrange *subrange ) {
    596614        return subrange;
    597615}
    598616
    599617
    600 Constant *Mutator::mutate( Constant *constant ) {
     618Constant * Mutator::mutate( Constant *constant ) {
    601619        return constant;
    602620}
  • src/SynTree/Mutator.h

    r0c6596f r1cb758f2  
    4949        virtual Statement* mutate( CatchStmt *catchStmt );
    5050        virtual Statement* mutate( FinallyStmt *catchStmt );
     51        virtual Statement* mutate( WaitForStmt *waitforStmt );
    5152        virtual NullStmt* mutate( NullStmt *nullStmt );
    5253        virtual Statement* mutate( DeclStmt *declStmt );
  • src/SynTree/Statement.cc

    r0c6596f r1cb758f2  
    419419}
    420420
     421WaitForStmt::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
     429WaitForStmt::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
     446WaitForStmt::~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
     462void 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
    421469NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}
    422470NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}
  • src/SynTree/Statement.h

    r0c6596f r1cb758f2  
    1919#include <list>                    // for list
    2020#include <memory>                  // for allocator
     21#include <vector>                        // for vector
    2122
    2223#include "BaseSyntaxNode.h"        // for BaseSyntaxNode
     
    392393};
    393394
     395class 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
    394433
    395434// represents a declaration that occurs as part of a compound statement
  • src/SynTree/SynTree.h

    r0c6596f r1cb758f2  
    5454class CatchStmt;
    5555class FinallyStmt;
     56class WaitForStmt;
    5657class NullStmt;
    5758class DeclStmt;
  • src/SynTree/Visitor.cc

    r0c6596f r1cb758f2  
    155155}
    156156
     157void 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
    157173void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) {
    158174}
  • src/SynTree/Visitor.h

    r0c6596f r1cb758f2  
    5151        virtual void visit( CatchStmt *catchStmt );
    5252        virtual void visit( FinallyStmt *finallyStmt );
     53        virtual void visit( WaitForStmt *waitforStmt );
    5354        virtual void visit( NullStmt *nullStmt );
    5455        virtual void visit( DeclStmt *declStmt );
  • src/libcfa/concurrency/invoke.h

    r0c6596f r1cb758f2  
    2828      #define thread_local _Thread_local
    2929
     30      typedef void (*fptr_t)();
     31
    3032      struct spinlock {
    3133            volatile int lock;
     
    5052            void append( struct __thread_queue_t *, struct thread_desc * );
    5153            struct thread_desc * pop_head( struct __thread_queue_t * );
     54            struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** );
    5255
    5356            void ?{}( struct __condition_stack_t & );
     
    8790            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    8891            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       };
    9097
    9198      struct thread_desc {
     99            // Core threading fields
    92100            struct coroutine_desc cor;                // coroutine body used to store context
    93101            struct monitor_desc mon;                  // monitor body used for mutual exclusion
     102
     103            // Link lists fields
    94104            struct thread_desc * next;                // instrusive link field for threads
     105
     106            // Current status related to monitors
    95107            struct monitor_desc ** current_monitors;  // currently held monitors
    96108            unsigned short current_monitor_count;     // number of currently held monitors
    97       };
     109            fptr_t current_monitor_func;              // last function that acquired monitors
     110     };
    98111
    99112#endif //_INVOKE_H_
  • src/libcfa/concurrency/kernel.c

    r0c6596f r1cb758f2  
    322322void ScheduleThread( thread_desc * thrd ) {
    323323        // if( !thrd ) return;
    324         assert( thrd );
    325         assert( thrd->cor.state != Halted );
     324        verify( thrd );
     325        verify( thrd->cor.state != Halted );
    326326
    327327        verify( disable_preempt_count > 0 );
     
    366366
    367367void BlockInternal( thread_desc * thrd ) {
     368        assert(thrd);
    368369        disable_interrupts();
    369370        assert( thrd->cor.state != Halted );
     
    379380
    380381void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     382        assert(thrd);
    381383        disable_interrupts();
    382384        this_processor->finish.action_code = Release_Schedule;
     
    666668}
    667669
     670thread_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
    668687void ?{}( __condition_stack_t & this ) {
    669688        this.top = NULL;
  • src/libcfa/concurrency/monitor

    r0c6596f r1cb758f2  
    2323
    2424static inline void ?{}(monitor_desc & this) {
     25        (this.lock){};
    2526        this.owner = NULL;
     27        (this.entry_queue){};
     28        (this.signal_stack){};
    2629        this.recursion = 0;
     30        this.acceptables = NULL;
     31        this.acceptable_count = 0;
     32        this.accepted_index = -1;
    2733}
    2834
     
    3238        monitor_desc ** prev_mntrs;
    3339        unsigned short  prev_count;
     40        fptr_t          prev_func;
    3441};
    3542
     
    3845}
    3946
    40 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count );
     47void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
    4148void ^?{}( monitor_guard_t & this );
    4249
     
    8996uintptr_t front( condition * this );
    9097
     98//-----------------------------------------------------------------------------
     99// External scheduling
     100
    91101struct __acceptable_t {
    92         void (*func)(void);
     102        fptr_t func;
    93103        unsigned short count;
    94         monitor_desc * monitors[1];
     104        monitor_desc ** monitors;
    95105};
    96106
    97 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) );
     107int __accept_internal( unsigned short count, __acceptable_t * acceptables );
    98108
    99109// Local Variables: //
  • src/libcfa/concurrency/monitor.c

    r0c6596f r1cb758f2  
    2525static inline void set_owner( monitor_desc * this, thread_desc * owner );
    2626static inline thread_desc * next_thread( monitor_desc * this );
     27static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() );
    2728
    2829static inline void lock_all( spinlock ** locks, unsigned short count );
     
    3435static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count );
    3536
     37static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     38static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
     39
    3640static inline thread_desc * check_condition( __condition_criterion_t * );
    3741static inline void brand_condition( condition * );
    3842static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
    3943
     44static 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
    4064//-----------------------------------------------------------------------------
    4165// Enter/Leave routines
     
    4367
    4468extern "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
    4672                lock_yield( &this->lock DEBUG_CTX2 );
    4773                thread_desc * thrd = this_thread;
    4874
    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;
    5178                if( !this->owner ) {
    52                         //No one has the monitor, just take it
     79                        // No one has the monitor, just take it
    5380                        set_owner( this, thrd );
     81
     82                        LIB_DEBUG_PRINT_SAFE("Kernel :  mon is free \n");
    5483                }
    5584                else if( this->owner == thrd) {
    56                         //We already have the monitor, just not how many times we took it
     85                        // We already have the monitor, just not how many times we took it
    5786                        verify( this->recursion > 0 );
    5887                        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");
    5996                }
    6097                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
    62101                        append( &this->entry_queue, thrd );
    63                         // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
    64102                        BlockInternal( &this->lock );
    65103
    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
    67107                        return;
    68108                }
    69109
     110                LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
     111
     112                // Release the lock and leave
    70113                unlock( &this->lock );
    71114                return;
    72115        }
    73116
    74         // leave pseudo code :
    75         //      TODO
     117        // Leave single monitor
    76118        void __leave_monitor_desc( monitor_desc * this ) {
     119                // Lock the monitor spinlock, lock_yield to reduce contention
    77120                lock_yield( &this->lock DEBUG_CTX2 );
    78121
    79                 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);
    80122                verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
    81123
    82                 //Leaving a recursion level, decrement the counter
     124                // Leaving a recursion level, decrement the counter
    83125                this->recursion -= 1;
    84126
    85                 //If we haven't left the last level of recursion
    86                 //it means we don't need to do anything
     127                // If we haven't left the last level of recursion
     128                // it means we don't need to do anything
    87129                if( this->recursion != 0) {
    88130                        unlock( &this->lock );
     
    90132                }
    91133
     134                // Get the next thread, will be null on low contention monitor
    92135                thread_desc * new_owner = next_thread( this );
    93136
    94                 //We can now let other threads in safely
     137                // We can now let other threads in safely
    95138                unlock( &this->lock );
    96 
    97                 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
    98139
    99140                //We need to wake-up the thread
     
    101142        }
    102143
     144        // Leave the thread monitor
     145        // last routine called by a thread.
     146        // Should never return
    103147        void __leave_thread_monitor( thread_desc * thrd ) {
    104148                monitor_desc * this = &thrd->mon;
     149
     150                // Lock the monitor now
    105151                lock_yield( &this->lock DEBUG_CTX2 );
    106152
     
    111157                verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
    112158
    113                 //Leaving a recursion level, decrement the counter
     159                // Leaving a recursion level, decrement the counter
    114160                this->recursion -= 1;
    115161
    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
    123167                thread_desc * new_owner = next_thread( this );
    124168
     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
    125172                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
     180static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) {
    130181        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
    135188static inline void leave(monitor_desc ** monitors, int count) {
    136189        for(int i = count - 1; i >= 0; i--) {
     
    139192}
    140193
    141 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count ) {
     194// Ctor for monitor guard
     195// Sorts monitors before entering
     196void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
     197        // Store current array
    142198        this.m = m;
    143199        this.count = count;
     200
     201        // Sort monitors based on address -> TODO use a sort specialized for small numbers
    144202        qsort(this.m, count);
    145         enter( this.m, this.count );
    146 
     203
     204        // Save previous thread context
    147205        this.prev_mntrs = this_thread->current_monitors;
    148206        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)
    150210        this_thread->current_monitors      = m;
    151211        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
    154220void ^?{}( monitor_guard_t & this ) {
     221        // Leave the monitors in order
    155222        leave( this.m, this.count );
    156223
     224        // Restore thread context
    157225        this_thread->current_monitors      = this.prev_mntrs;
    158226        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
    161232void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
    162233        this.waiting_thread = waiting_thread;
     
    183254// Internal scheduling
    184255void wait( condition * this, uintptr_t user_info = 0 ) {
    185         // LIB_DEBUG_PRINT_SAFE("Waiting\n");
    186 
    187256        brand_condition( this );
    188257
    189         //Check that everything is as expected
     258        // Check that everything is as expected
    190259        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
    191260        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    192261        verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
    193262
    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
    209271        append( &this->blocked, &waiter );
    210272
    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
    216282        unsigned short thread_count = 0;
    217283        thread_desc * threads[ count ];
     
    220286        }
    221287
     288        // Remove any duplicate threads
    222289        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] );
    224291                thread_count = insert_unique( threads, thread_count, new_owner );
    225292        }
    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");
    232293
    233294        // Everything is ready to go to sleep
     
    235296
    236297
    237         //WE WOKE UP
    238 
    239 
    240         //We are back, restore the owners and recursions
     298        // WE WOKE UP
     299
     300
     301        // We are back, restore the owners and recursions
    241302        lock_all( locks, count );
    242         restore_recursion( this->monitors, recursions, count );
     303        restore_recursion( monitors, recursions, count );
    243304        unlock_all( locks, count );
    244305}
    245306
    246307bool 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; }
    251309
    252310        //Check that everything is as expected
    253311        verify( this->monitors );
    254312        verify( this->monitor_count != 0 );
    255 
    256         unsigned short count = this->monitor_count;
    257313
    258314        //Some more checking in debug
     
    261317                if ( this->monitor_count != this_thrd->current_monitor_count ) {
    262318                        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                 } // if
     319                }
    264320
    265321                for(int i = 0; i < this->monitor_count; i++) {
    266322                        if ( this->monitors[i] != this_thrd->current_monitors[i] ) {
    267323                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] );
    268                         } // if
     324                        }
    269325                }
    270326        );
    271327
    272         //Lock all the monitors
     328        unsigned short count = this->monitor_count;
     329
     330        // Lock all monitors
    273331        lock_all( this->monitors, NULL, count );
    274         // LIB_DEBUG_PRINT_SAFE("Signalling");
    275332
    276333        //Pop the head of the waiting queue
     
    280337        for(int i = 0; i < count; i++) {
    281338                __condition_criterion_t * crit = &node->criteria[i];
    282                 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
    283339                assert( !crit->ready );
    284340                push( &crit->target->signal_stack, crit );
    285341        }
    286342
    287         // LIB_DEBUG_PRINT_SAFE("\n");
    288 
    289343        //Release
    290344        unlock_all( this->monitors, count );
     
    294348
    295349bool 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; }
    300351
    301352        //Check that everything is as expected
     
    303354        verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    304355
    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 )
    322364
    323365        //save contexts
    324         save_recursion( this->monitors, recursions, count );
     366        save_recursion( monitors, recursions, count );
    325367
    326368        //Find the thread to run
    327369        thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
    328370        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        }
    333373
    334374        //Everything is ready to go to sleep
     
    336376
    337377
    338 
    339 
    340         LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
     378        // WE WOKE UP
     379
    341380
    342381        //We are back, restore the owners and recursions
    343382        lock_all( locks, count );
    344         restore_recursion( this->monitors, recursions, count );
     383        restore_recursion( monitors, recursions, count );
    345384        unlock_all( locks, count );
    346385
     
    348387}
    349388
     389// Access the user_info of the thread waiting at the front of the queue
    350390uintptr_t front( condition * this ) {
    351391        verifyf( !is_empty(this),
     
    358398//-----------------------------------------------------------------------------
    359399// 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 );
     400int __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;
    384454}
    385455
     
    415485}
    416486
     487static 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
     523static 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
     531static 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
    417540static inline void lock_all( spinlock ** locks, unsigned short count ) {
    418541        for( int i = 0; i < count; i++ ) {
     
    505628}
    506629
     630
     631static 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
     639static 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}
    507663void ?{}( __condition_blocked_queue_t & this ) {
    508664        this.head = NULL;
  • src/libcfa/concurrency/preemption.c

    r0c6596f r1cb758f2  
    332332                assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int);
    333333
    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 );
    335335                // Switch on the code (a.k.a. the sender) to
    336336                switch( info.si_code )
     
    340340                case SI_TIMER:
    341341                case SI_KERNEL:
    342                         LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
     342                        // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
    343343                        lock( &event_kernel->lock DEBUG_CTX2 );
    344344                        tick_preemption();
  • src/tests/gmp.c

    r0c6596f r1cb758f2  
    1010// Created On       : Tue Apr 19 08:55:51 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 24 09:33:26 2017
    13 // Update Count     : 543
     12// Last Modified On : Fri Aug 25 12:50:01 2017
     13// Update Count     : 544
    1414//
     15
     16// NOTE: UBUNTU DOES NOT SUPPORT GMP MULTILIB, SO ONLY 64-BIT GMP IS TESTED.
    1517
    1618#include <gmp>
  • src/tests/preempt_longrun/stack.c

    r0c6596f r1cb758f2  
    1515
    1616void 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++) {
    2121                n *= a;
    2222                n %= p;
  • src/tests/sched-int-disjoint.c

    r0c6596f r1cb758f2  
    33#include <monitor>
    44#include <thread>
     5
     6#include <time.h>
    57
    68static const unsigned long N = 10_000ul;
     
    107109// Main loop
    108110int main(int argc, char* argv[]) {
     111        rand48seed( time( NULL ) );
    109112        all_done = false;
    110113        processor p;
  • src/tests/sched-int-wait.c

    r0c6596f r1cb758f2  
    55#include <thread>
    66
    7 static const unsigned long N = 10_000ul;
     7#include <time.h>
     8
     9static const unsigned long N = 2_500ul;
    810
    911#ifndef PREEMPTION_RATE
     
    119121// Main
    120122int main(int argc, char* argv[]) {
     123        rand48seed( time( NULL ) );
    121124        waiter_left = 4;
    122125        processor p[2];
  • src/tests/switch.c

    r0c6596f r1cb758f2  
    1010// Created On       : Tue Jul 12 06:50:22 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug  4 11:44:29 2016
    13 // Update Count     : 31
     12// Last Modified On : Sat Aug 26 10:14:21 2017
     13// Update Count     : 33
    1414//
    1515
    1616int f( int i ) { return i; }
    1717
    18 int main() {
     18int main( void ) {
    1919        int i = 0;
    2020        switch ( i ) case 3 : i = 1;
     
    100100                j = 5;
    101101        } // choose
    102 }
     102} // main
    103103
    104104// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.