Changeset aaa4f93


Ignore:
Timestamp:
Sep 21, 2017, 11:33:23 AM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
7453a68
Parents:
a2dbad10
Message:

Updated accepted index to live in the waitfor caller stack.
Waitfor no longer blocks if all when clauses are false.
Waitfor now properly zeroes out acceptables before use.

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Waitfor.cc

    ra2dbad10 raaa4f93  
    126126
    127127                ObjectDecl * declare( unsigned long count, CompoundStmt * stmt );
     128                ObjectDecl * declareFlag( CompoundStmt * stmt );
     129                Statement  * makeSetter( ObjectDecl * flag );
    128130                ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt );
    129                 void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
    130                 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
     131                void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * settter, CompoundStmt * stmt );
     132                Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, Statement * settter, CompoundStmt * stmt );
    131133                Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
    132134                void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
     
    140142          private:
    141143                FunctionDecl        * decl_waitfor    = nullptr;
     144                StructDecl          * decl_mask       = nullptr;
    142145                StructDecl          * decl_acceptable = nullptr;
    143146                StructDecl          * decl_monitor    = nullptr;
     
    145148                static std::unique_ptr< Type > generic_func;
    146149
     150                UniqueName namer_acc = "__acceptables_"s;
     151                UniqueName namer_idx = "__index_"s;
     152                UniqueName namer_flg = "__do_run_"s;
     153                UniqueName namer_msk = "__mask_"s;
    147154                UniqueName namer_mon = "__monitors_"s;
    148                 UniqueName namer_acc = "__acceptables_"s;
    149155                UniqueName namer_tim = "__timeout_"s;
    150                 UniqueName namer_ret = "__return_"s;
    151156        };
    152157
     
    239244                        decl_acceptable = decl;
    240245                }
     246                else if( decl->name == "__waitfor_mask_t" ) {
     247                        assert( !decl_mask );
     248                        decl_mask = decl;
     249                }
    241250                else if( decl->name == "monitor_desc" ) {
    242251                        assert( !decl_monitor );
     
    246255
    247256        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    248                 if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
     257                if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
    249258
    250259                CompoundStmt * stmt = new CompoundStmt( noLabels );
    251260
    252261                ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
     262                ObjectDecl * flag        = declareFlag( stmt );
     263                Statement  * setter      = makeSetter( flag );
    253264
    254265                int index = 0;
    255266                for( auto & clause : waitfor->clauses ) {
    256                         init( acceptables, index, clause, stmt );
     267                        init( acceptables, index, clause, setter, stmt );
    257268
    258269                        index++;
     
    264275                        waitfor->orelse .statement,
    265276                        waitfor->orelse .condition,
     277                        setter,
    266278                        stmt
    267279                );
    268280
    269                 Expression * result = call( waitfor->clauses.size(), acceptables, timeout, stmt );
    270 
    271                 choose( waitfor, result, stmt );
     281                CompoundStmt * compound = new CompoundStmt( noLabels );
     282                stmt->push_back( new IfStmt(
     283                        noLabels,
     284                        safeCond( new VariableExpr( flag ) ),
     285                        compound,
     286                        nullptr
     287                ));
     288
     289                Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound );
     290
     291                choose( waitfor, result, compound );
    272292
    273293                return stmt;
     
    293313                stmt->push_back( new DeclStmt( noLabels, acceptables) );
    294314
     315                UntypedExpr * set = new UntypedExpr(
     316                        new NameExpr( "__builtin_memset" ),
     317                        {
     318                                new VariableExpr( acceptables ),
     319                                new ConstantExpr( Constant::from_int( 0 ) ),
     320                                new SizeofExpr( new VariableExpr( acceptables ) )
     321                        }
     322                );
     323
     324                Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer );
     325                delete set;
     326
     327                stmt->push_back( new ExprStmt( noLabels, resolved_set ) );
     328
    295329                return acceptables;
     330        }
     331
     332        ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) {
     333                ObjectDecl * flag = ObjectDecl::newObject(
     334                        namer_flg.newName(),
     335                        new BasicType(
     336                                noQualifiers,
     337                                BasicType::Bool
     338                        ),
     339                        new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) )
     340                );
     341
     342                stmt->push_back( new DeclStmt( noLabels, flag) );
     343
     344                return flag;
     345        }
     346
     347        Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) {
     348                Expression * untyped = new UntypedExpr(
     349                        new NameExpr( "?=?" ),
     350                        {
     351                                new VariableExpr( flag ),
     352                                new ConstantExpr( Constant::from_ulong( 1 ) )
     353                        }
     354                );
     355
     356                Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer );
     357                delete untyped;
     358
     359                return new ExprStmt( noLabels, expr );
    296360        }
    297361
     
    341405        }
    342406
    343         void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
     407        void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) {
    344408
    345409                ObjectDecl * monitors = declMon( clause, stmt );
    346410
    347411                Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
    348 
    349                 CompoundStmt * compound = new CompoundStmt( noLabels );
    350                 compound->push_back( makeAccStatement( acceptables, index, "is_dtor" , detectIsDtor( clause.target.function )                                    , indexer ) );
    351                 compound->push_back( makeAccStatement( acceptables, index, "func"    , new CastExpr( clause.target.function, fptr_t )                            , indexer ) );
    352                 compound->push_back( makeAccStatement( acceptables, index, "monitors", new VariableExpr( monitors )                                              , indexer ) );
    353                 compound->push_back( makeAccStatement( acceptables, index, "count"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ) );
    354412
    355413                stmt->push_back( new IfStmt(
    356414                        noLabels,
    357415                        safeCond( clause.condition ),
    358                         compound,
     416                        new CompoundStmt({
     417                                makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function )                                    , indexer ),
     418                                makeAccStatement( acceptables, index, "func"   , new CastExpr( clause.target.function, fptr_t )                            , indexer ),
     419                                makeAccStatement( acceptables, index, "list"   , new VariableExpr( monitors )                                              , indexer ),
     420                                makeAccStatement( acceptables, index, "size"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ),
     421                                setter->clone()
     422                        }),
    359423                        nullptr
    360424                ));
     
    370434                bool has_else,
    371435                Expression *& else_cond,
     436                Statement * setter,
    372437                CompoundStmt * stmt
    373438        ) {
     
    389454                                noLabels,
    390455                                safeCond( time_cond ),
    391                                 new ExprStmt(
    392                                         noLabels,
    393                                         makeOpAssign(
    394                                                 new VariableExpr( timeout ),
    395                                                 time
    396                                         )
    397                                 ),
     456                                new CompoundStmt({
     457                                        new ExprStmt(
     458                                                noLabels,
     459                                                makeOpAssign(
     460                                                        new VariableExpr( timeout ),
     461                                                        time
     462                                                )
     463                                        ),
     464                                        setter->clone()
     465                                }),
    398466                                nullptr
    399467                        ));
     
    406474                                noLabels,
    407475                                safeCond( else_cond ),
    408                                 new ExprStmt(
    409                                         noLabels,
    410                                         makeOpAssign(
    411                                                 new VariableExpr( timeout ),
    412                                                 new ConstantExpr( Constant::from_ulong( 0 ) )
    413                                         )
    414                                 ),
     476                                new CompoundStmt({
     477                                        new ExprStmt(
     478                                                noLabels,
     479                                                makeOpAssign(
     480                                                        new VariableExpr( timeout ),
     481                                                        new ConstantExpr( Constant::from_ulong( 0 ) )
     482                                                )
     483                                        ),
     484                                        setter->clone()
     485                                }),
    415486                                nullptr
    416487                        ));
     
    418489                        else_cond = nullptr;
    419490                }
     491
     492                delete setter;
    420493
    421494                return new VariableExpr( timeout );
     
    428501                CompoundStmt * stmt
    429502        ) {
    430                 ObjectDecl * decl = ObjectDecl::newObject(
    431                         namer_ret.newName(),
     503                ObjectDecl * index = ObjectDecl::newObject(
     504                        namer_idx.newName(),
    432505                        new BasicType(
    433506                                noQualifiers,
    434                                 BasicType::LongLongUnsignedInt
     507                                BasicType::ShortSignedInt
    435508                        ),
    436509                        new SingleInit(
    437                                 new UntypedExpr(
    438                                         VariableExpr::functionPointer( decl_waitfor ),
    439                                         {
    440                                                 new ConstantExpr( Constant::from_ulong( count ) ),
    441                                                 new VariableExpr( acceptables ),
    442                                                 timeout
    443                                         }
    444                                 )
     510                                new ConstantExpr( Constant::from_int( -1 ) )
    445511                        )
    446512                );
    447513
    448                 stmt->push_back( new DeclStmt( noLabels, decl ) );
    449 
    450                 return new VariableExpr( decl );
     514                stmt->push_back( new DeclStmt( noLabels, index ) );
     515
     516                ObjectDecl * mask = ObjectDecl::newObject(
     517                        namer_msk.newName(),
     518                        new StructInstType(
     519                                noQualifiers,
     520                                decl_mask
     521                        ),
     522                        new ListInit({
     523                                new SingleInit( new AddressExpr( new VariableExpr( index ) ) ),
     524                                new SingleInit( new VariableExpr( acceptables ) ),
     525                                new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) )
     526                        })
     527                );
     528
     529                stmt->push_back( new DeclStmt( noLabels, mask ) );
     530
     531                stmt->push_back( new ExprStmt(
     532                        noLabels,
     533                        new ApplicationExpr(
     534                                VariableExpr::functionPointer( decl_waitfor ),
     535                                {
     536                                        new CastExpr(
     537                                                new VariableExpr( mask ),
     538                                                new ReferenceType(
     539                                                        noQualifiers,
     540                                                        new StructInstType(
     541                                                                noQualifiers,
     542                                                                decl_mask
     543                                                        )
     544                                                )
     545                                        ),
     546                                        timeout
     547                                }
     548                        )
     549                ));
     550
     551                return new VariableExpr( index );
    451552        }
    452553
  • src/libcfa/concurrency/monitor

    ra2dbad10 raaa4f93  
    105105
    106106struct __acceptable_t {
    107         __monitor_group_t monitors;
     107        __monitor_group_t;
    108108        bool is_dtor;
    109109};
  • src/libcfa/concurrency/monitor.c

    ra2dbad10 raaa4f93  
    280280        lock_all( monitors, locks, count );
    281281
    282         // DON'T unlock, ask the kernel to do it
    283 
    284         // Save monitor state
    285         save_recursion( monitors, recursions, count );
    286 
    287282        // Find the next thread(s) to run
    288283        unsigned short thread_count = 0;
     
    297292                thread_count = insert_unique( threads, thread_count, new_owner );
    298293        }
     294
     295        // Save monitor state
     296        save_recursion( monitors, recursions, count );
    299297
    300298        // Everything is ready to go to sleep
     
    634632        // For all acceptable functions check if this is the current function.
    635633        for( short i = 0; i < count; i++, it++ ) {
    636                 if( it->monitors == group ) {
     634                if( *it == group ) {
    637635                        *this->mask.accepted = i;
    638636                        return true;
     
    658656                for( __acceptable_t * it = mask.clauses; it != end; it++, i++ ) {
    659657                        // Check if we have a match
    660                         if( it->monitors == (*thrd_it)->monitors ) {
     658                        if( *it == (*thrd_it)->monitors ) {
    661659
    662660                                // If we have a match return it
     
    673671        short max = 0;
    674672        for( int i = 0; i < mask.size; i++ ) {
    675                 max += mask.clauses[i].monitors.size;
     673                max += mask.clauses[i].size;
    676674        }
    677675        return max;
Note: See TracChangeset for help on using the changeset viewer.