Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Waitfor.cc

    raaa4f93 re3e16bc  
    2727#include "InitTweak/InitTweak.h"   // for getPointerBase
    2828#include "Parser/LinkageSpec.h"    // for Cforall
    29 #include "ResolvExpr/Resolver.h"   // for findVoidExpression
     29#include "SymTab/AddVisit.h"       // for acceptAndAdd
    3030#include "SynTree/Constant.h"      // for Constant
    3131#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    112112        //=============================================================================================
    113113
    114         class GenerateWaitForPass final : public WithIndexer {
     114        class GenerateWaitForPass final : public WithStmtsToAdd {
    115115          public:
    116116
     
    126126
    127127                ObjectDecl * declare( unsigned long count, CompoundStmt * stmt );
    128                 ObjectDecl * declareFlag( CompoundStmt * stmt );
    129                 Statement  * makeSetter( ObjectDecl * flag );
    130128                ObjectDecl * declMon( WaitForStmt::Clause & clause, 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 );
    133                 Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
    134                 void         choose( WaitForStmt * waitfor, Expression  * result, 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                Expression * call();
     132                void choose();
    135133
    136134                static void implement( std::list< Declaration * > & translationUnit ) {
     
    142140          private:
    143141                FunctionDecl        * decl_waitfor    = nullptr;
    144                 StructDecl          * decl_mask       = nullptr;
    145142                StructDecl          * decl_acceptable = nullptr;
    146143                StructDecl          * decl_monitor    = nullptr;
     144                DeclarationWithType * decl_m_func     = nullptr;
     145                DeclarationWithType * decl_m_count    = nullptr;
     146                DeclarationWithType * decl_m_monitors = nullptr;
     147                DeclarationWithType * decl_m_isdtor   = nullptr;
    147148
    148149                static std::unique_ptr< Type > generic_func;
    149150
     151                UniqueName namer_mon = "__monitors_"s;
    150152                UniqueName namer_acc = "__acceptables_"s;
    151                 UniqueName namer_idx = "__index_"s;
    152                 UniqueName namer_flg = "__do_run_"s;
    153                 UniqueName namer_msk = "__mask_"s;
    154                 UniqueName namer_mon = "__monitors_"s;
    155153                UniqueName namer_tim = "__timeout_"s;
    156154        };
     
    169167        namespace {
    170168                Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
    171                         return new UntypedExpr(
     169                        return new ApplicationExpr(
    172170                                new NameExpr( "?[?]" ),
    173171                                {
     
    179177
    180178                Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
    181                         return new UntypedExpr(
     179                        return new ApplicationExpr(
    182180                                        new NameExpr( "?=?" ),
    183181                                        { lhs, rhs }
     
    185183                }
    186184
    187                 Expression * makeOpMember( Expression * sue, const std::string & mem ) {
    188                         return new UntypedMemberExpr( new NameExpr( mem ), sue );
    189                 }
    190 
    191                 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
    192                         std::unique_ptr< Expression > expr( makeOpAssign(
    193                                 makeOpMember(
    194                                         makeOpIndex(
    195                                                 object,
    196                                                 index
     185                Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) {
     186                        return new MemberExpr( mem, sue );
     187                }
     188
     189                Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) {
     190                        return new ExprStmt(
     191                                noLabels,
     192                                makeOpAssign(
     193                                        makeOpMember(
     194                                                makeOpIndex(
     195                                                        object,
     196                                                        index
     197                                                ),
     198                                                member
    197199                                        ),
    198                                         member
    199                                 ),
    200                                 value
    201                         ) );
    202 
    203                         return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
     200                                        value
     201                                )
     202                        );
    204203                }
    205204
     
    209208                        return new ConstantExpr( Constant::from_bool( ifnull ) );
    210209                }
    211 
    212                 VariableExpr * extractVariable( Expression * func ) {
    213                         if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) {
    214                                 return var;
    215                         }
    216 
    217                         CastExpr * cast = strict_dynamic_cast< CastExpr * >( func );
    218                         return strict_dynamic_cast< VariableExpr * >( cast->arg );
    219                 }
    220 
    221                 Expression * detectIsDtor( Expression * func ) {
    222                         VariableExpr * typed_func = extractVariable( func );
    223                         bool is_dtor = InitTweak::isDestructor( typed_func->var );
    224                         return new ConstantExpr( Constant::from_bool( is_dtor ) );
    225                 }
    226210        };
    227211
     
    232216
    233217        void GenerateWaitForPass::premutate( FunctionDecl * decl) {
    234                 if( decl->name != "__waitfor_internal" ) return;
     218                if( decl->name != "__accept_internal" ) return;
    235219
    236220                decl_waitfor = decl;
     
    243227                        assert( !decl_acceptable );
    244228                        decl_acceptable = decl;
    245                 }
    246                 else if( decl->name == "__waitfor_mask_t" ) {
    247                         assert( !decl_mask );
    248                         decl_mask = decl;
     229                        for( Declaration * field : decl_acceptable->members ) {
     230                                     if( field->name == "func"    ) decl_m_func     = strict_dynamic_cast< DeclarationWithType * >( field );
     231                                else if( field->name == "count"   ) decl_m_count    = strict_dynamic_cast< DeclarationWithType * >( field );
     232                                else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field );
     233                                else if( field->name == "is_dtor" ) decl_m_isdtor   = strict_dynamic_cast< DeclarationWithType * >( field );
     234                        }
     235
    249236                }
    250237                else if( decl->name == "monitor_desc" ) {
     
    255242
    256243        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    257                 if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
     244                return waitfor;
     245
     246                if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
    258247
    259248                CompoundStmt * stmt = new CompoundStmt( noLabels );
    260249
    261250                ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
    262                 ObjectDecl * flag        = declareFlag( stmt );
    263                 Statement  * setter      = makeSetter( flag );
    264251
    265252                int index = 0;
    266253                for( auto & clause : waitfor->clauses ) {
    267                         init( acceptables, index, clause, setter, stmt );
     254                        init( acceptables, index, clause, stmt );
    268255
    269256                        index++;
     
    275262                        waitfor->orelse .statement,
    276263                        waitfor->orelse .condition,
    277                         setter,
    278264                        stmt
    279265                );
    280266
    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 );
     267                // Expression * result  = call( acceptables, timeout, orelse, stmt );
     268
     269                // choose( waitfor, result );
    292270
    293271                return stmt;
     
    296274        ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
    297275        {
    298                 ObjectDecl * acceptables = ObjectDecl::newObject(
     276                ObjectDecl * acceptables = new ObjectDecl(
    299277                        namer_acc.newName(),
     278                        noStorage,
     279                        LinkageSpec::Cforall,
     280                        nullptr,
    300281                        new ArrayType(
    301282                                noQualifiers,
     
    313294                stmt->push_back( new DeclStmt( noLabels, acceptables) );
    314295
    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 
    329296                return acceptables;
    330297        }
    331298
    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 );
    360         }
    361 
    362299        ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    363300
    364                 ObjectDecl * mon = ObjectDecl::newObject(
     301                ObjectDecl * mon = new ObjectDecl(
    365302                        namer_mon.newName(),
     303                        noStorage,
     304                        LinkageSpec::Cforall,
     305                        nullptr,
    366306                        new ArrayType(
    367307                                noQualifiers,
    368                                 new PointerType(
     308                                new StructInstType(
    369309                                        noQualifiers,
    370                                         new StructInstType(
    371                                                 noQualifiers,
    372                                                 decl_monitor
    373                                         )
     310                                        decl_monitor
    374311                                ),
    375312                                new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ),
     
    379316                        new ListInit(
    380317                                map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
    381                                         Expression * untyped = new CastExpr(
    382                                                 new UntypedExpr(
    383                                                         new NameExpr( "get_monitor" ),
    384                                                         { expr }
    385                                                 ),
    386                                                 new PointerType(
    387                                                         noQualifiers,
    388                                                         new StructInstType(
    389                                                                 noQualifiers,
    390                                                                 decl_monitor
    391                                                         )
    392                                                 )
    393                                         );
    394 
    395                                         Expression * init = ResolvExpr::findSingleExpression( untyped, indexer );
    396                                         delete untyped;
    397                                         return new SingleInit( init );
     318                                        return new SingleInit( expr );
    398319                                })
    399320                        )
     
    405326        }
    406327
    407         void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) {
     328        void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    408329
    409330                ObjectDecl * monitors = declMon( clause, stmt );
    410331
    411                 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
     332                CompoundStmt * compound = new CompoundStmt( noLabels );
     333                compound->push_back( makeAccStatement( acceptables, index, decl_m_func    , clause.target.function ) );
     334                compound->push_back( makeAccStatement( acceptables, index, decl_m_count   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) );
     335                compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) );
     336                compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor  , new ConstantExpr( Constant::from_bool( true ) ) ) );
    412337
    413338                stmt->push_back( new IfStmt(
    414339                        noLabels,
    415340                        safeCond( clause.condition ),
    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                         }),
     341                        compound,
    423342                        nullptr
    424343                ));
     
    434353                bool has_else,
    435354                Expression *& else_cond,
    436                 Statement * setter,
    437355                CompoundStmt * stmt
    438356        ) {
    439                 ObjectDecl * timeout = ObjectDecl::newObject(
     357                ObjectDecl * timeout = new ObjectDecl(
    440358                        namer_tim.newName(),
     359                        noStorage,
     360                        LinkageSpec::Cforall,
     361                        nullptr,
    441362                        new BasicType(
    442363                                noQualifiers,
     
    453374                        stmt->push_back( new IfStmt(
    454375                                noLabels,
    455                                 safeCond( time_cond ),
    456                                 new CompoundStmt({
    457                                         new ExprStmt(
    458                                                 noLabels,
    459                                                 makeOpAssign(
    460                                                         new VariableExpr( timeout ),
    461                                                         time
    462                                                 )
    463                                         ),
    464                                         setter->clone()
    465                                 }),
     376                                safeCond( else_cond ),
     377                                new ExprStmt(
     378                                        noLabels,
     379                                        makeOpAssign(
     380                                                new VariableExpr( timeout ),
     381                                                time
     382                                        )
     383                                ),
    466384                                nullptr
    467385                        ));
     
    474392                                noLabels,
    475393                                safeCond( else_cond ),
    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                                 }),
     394                                new ExprStmt(
     395                                        noLabels,
     396                                        makeOpAssign(
     397                                                new VariableExpr( timeout ),
     398                                                new ConstantExpr( Constant::from_ulong( 0 ) )
     399                                        )
     400                                ),
    486401                                nullptr
    487402                        ));
     
    490405                }
    491406
    492                 delete setter;
    493 
    494407                return new VariableExpr( timeout );
    495         }
    496 
    497         Expression * GenerateWaitForPass::call(
    498                 size_t count,
    499                 ObjectDecl * acceptables,
    500                 Expression * timeout,
    501                 CompoundStmt * stmt
    502         ) {
    503                 ObjectDecl * index = ObjectDecl::newObject(
    504                         namer_idx.newName(),
    505                         new BasicType(
    506                                 noQualifiers,
    507                                 BasicType::ShortSignedInt
    508                         ),
    509                         new SingleInit(
    510                                 new ConstantExpr( Constant::from_int( -1 ) )
    511                         )
    512                 );
    513 
    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 );
    552         }
    553 
    554         void GenerateWaitForPass::choose(
    555                 WaitForStmt * waitfor,
    556                 Expression  * result,
    557                 CompoundStmt * stmt
    558         ) {
    559                 SwitchStmt * swtch = new SwitchStmt(
    560                         noLabels,
    561                         result,
    562                         std::list<Statement *>()
    563                 );
    564 
    565                 unsigned long i = 0;
    566                 for( auto & clause : waitfor->clauses ) {
    567                         swtch->statements.push_back(
    568                                 new CaseStmt(
    569                                         noLabels,
    570                                         new ConstantExpr( Constant::from_ulong( i++ ) ),
    571                                         {
    572                                                 clause.statement,
    573                                                 new BranchStmt(
    574                                                         noLabels,
    575                                                         "",
    576                                                         BranchStmt::Break
    577                                                 )
    578                                         }
    579                                 )
    580                         );
    581                 }
    582 
    583                 if(waitfor->timeout.statement) {
    584                         swtch->statements.push_back(
    585                                 new CaseStmt(
    586                                         noLabels,
    587                                         new ConstantExpr( Constant::from_int( -2 ) ),
    588                                         {
    589                                                 waitfor->timeout.statement,
    590                                                 new BranchStmt(
    591                                                         noLabels,
    592                                                         "",
    593                                                         BranchStmt::Break
    594                                                 )
    595                                         }
    596                                 )
    597                         );
    598                 }
    599 
    600                 if(waitfor->orelse.statement) {
    601                         swtch->statements.push_back(
    602                                 new CaseStmt(
    603                                         noLabels,
    604                                         new ConstantExpr( Constant::from_int( -1 ) ),
    605                                         {
    606                                                 waitfor->orelse.statement,
    607                                                 new BranchStmt(
    608                                                         noLabels,
    609                                                         "",
    610                                                         BranchStmt::Break
    611                                                 )
    612                                         }
    613                                 )
    614                         );
    615                 }
    616 
    617                 stmt->push_back( swtch );
    618408        }
    619409};
Note: See TracChangeset for help on using the changeset viewer.