Changeset 1dcd9554 for src/Concurrency


Ignore:
Timestamp:
Sep 14, 2017, 3:42:14 PM (8 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:
310e5b7
Parents:
f92c696
Message:

First "working" implementation of waitfor

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Waitfor.cc

    rf92c696 r1dcd9554  
    2727#include "InitTweak/InitTweak.h"   // for getPointerBase
    2828#include "Parser/LinkageSpec.h"    // for Cforall
    29 #include "SymTab/AddVisit.h"       // for acceptAndAdd
     29#include "ResolvExpr/Resolver.h"   // for findVoidExpression
    3030#include "SynTree/Constant.h"      // for Constant
    3131#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    112112        //=============================================================================================
    113113
    114         class GenerateWaitForPass final : public WithStmtsToAdd {
     114        class GenerateWaitForPass final : public WithIndexer {
    115115          public:
    116116
     
    129129                void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
    130130                Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
    131                 Expression * call();
    132                 void choose();
     131                Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
     132                void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
    133133
    134134                static void implement( std::list< Declaration * > & translationUnit ) {
     
    142142                StructDecl          * decl_acceptable = nullptr;
    143143                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;
    148144
    149145                static std::unique_ptr< Type > generic_func;
     
    152148                UniqueName namer_acc = "__acceptables_"s;
    153149                UniqueName namer_tim = "__timeout_"s;
     150                UniqueName namer_ret = "__return_"s;
    154151        };
    155152
     
    167164        namespace {
    168165                Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
    169                         return new ApplicationExpr(
     166                        return new UntypedExpr(
    170167                                new NameExpr( "?[?]" ),
    171168                                {
     
    177174
    178175                Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
    179                         return new ApplicationExpr(
     176                        return new UntypedExpr(
    180177                                        new NameExpr( "?=?" ),
    181178                                        { lhs, rhs }
     
    183180                }
    184181
    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
     182                Expression * makeOpMember( Expression * sue, const std::string & mem ) {
     183                        return new UntypedMemberExpr( new NameExpr( mem ), sue );
     184                }
     185
     186                Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
     187                        std::unique_ptr< Expression > expr( makeOpAssign(
     188                                makeOpMember(
     189                                        makeOpIndex(
     190                                                object,
     191                                                index
    199192                                        ),
    200                                         value
    201                                 )
    202                         );
     193                                        member
     194                                ),
     195                                value
     196                        ) );
     197
     198                        return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
    203199                }
    204200
     
    227223                        assert( !decl_acceptable );
    228224                        decl_acceptable = 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 
    236225                }
    237226                else if( decl->name == "monitor_desc" ) {
     
    242231
    243232        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    244                 return waitfor;
    245 
    246233                if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
    247234
     
    265252                );
    266253
    267                 // Expression * result  = call( acceptables, timeout, orelse, stmt );
    268 
    269                 // choose( waitfor, result );
     254                Expression * result = call( waitfor->clauses.size(), acceptables, timeout, stmt );
     255
     256                choose( waitfor, result, stmt );
    270257
    271258                return stmt;
     
    274261        ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
    275262        {
    276                 ObjectDecl * acceptables = new ObjectDecl(
     263                ObjectDecl * acceptables = ObjectDecl::newObject(
    277264                        namer_acc.newName(),
    278                         noStorage,
    279                         LinkageSpec::Cforall,
    280                         nullptr,
    281265                        new ArrayType(
    282266                                noQualifiers,
     
    299283        ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
    300284
    301                 ObjectDecl * mon = new ObjectDecl(
     285                ObjectDecl * mon = ObjectDecl::newObject(
    302286                        namer_mon.newName(),
    303                         noStorage,
    304                         LinkageSpec::Cforall,
    305                         nullptr,
    306287                        new ArrayType(
    307288                                noQualifiers,
     
    330311                ObjectDecl * monitors = declMon( clause, stmt );
    331312
     313                Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
     314
    332315                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 ) ) ) );
     316                compound->push_back( makeAccStatement( acceptables, index, "func"    , new CastExpr( clause.target.function, fptr_t )                            , indexer ) );
     317                compound->push_back( makeAccStatement( acceptables, index, "count"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ) );
     318                compound->push_back( makeAccStatement( acceptables, index, "monitors", new VariableExpr( monitors )                                              , indexer ) );
     319                compound->push_back( makeAccStatement( acceptables, index, "is_dtor" , new ConstantExpr( Constant::from_bool( true ) )                           , indexer ) );
    337320
    338321                stmt->push_back( new IfStmt(
     
    355338                CompoundStmt * stmt
    356339        ) {
    357                 ObjectDecl * timeout = new ObjectDecl(
     340                ObjectDecl * timeout = ObjectDecl::newObject(
    358341                        namer_tim.newName(),
    359                         noStorage,
    360                         LinkageSpec::Cforall,
    361                         nullptr,
    362342                        new BasicType(
    363343                                noQualifiers,
     
    374354                        stmt->push_back( new IfStmt(
    375355                                noLabels,
    376                                 safeCond( else_cond ),
     356                                safeCond( time_cond ),
    377357                                new ExprStmt(
    378358                                        noLabels,
     
    407387                return new VariableExpr( timeout );
    408388        }
     389
     390        Expression * GenerateWaitForPass::call(
     391                size_t count,
     392                ObjectDecl * acceptables,
     393                Expression * timeout,
     394                CompoundStmt * stmt
     395        ) {
     396                ObjectDecl * decl = ObjectDecl::newObject(
     397                        namer_ret.newName(),
     398                        new BasicType(
     399                                noQualifiers,
     400                                BasicType::LongLongUnsignedInt
     401                        ),
     402                        new SingleInit(
     403                                new UntypedExpr(
     404                                        VariableExpr::functionPointer( decl_waitfor ),
     405                                        {
     406                                                new ConstantExpr( Constant::from_ulong( count ) ),
     407                                                new VariableExpr( acceptables ),
     408                                                timeout
     409                                        }
     410                                )
     411                        )
     412                );
     413
     414                stmt->push_back( new DeclStmt( noLabels, decl ) );
     415
     416                return new VariableExpr( decl );
     417        }
     418
     419        void GenerateWaitForPass::choose(
     420                WaitForStmt * waitfor,
     421                Expression  * result,
     422                CompoundStmt * stmt
     423        ) {
     424                SwitchStmt * swtch = new SwitchStmt(
     425                        noLabels,
     426                        result,
     427                        std::list<Statement *>()
     428                );
     429
     430                unsigned long i = 0;
     431                for( auto & clause : waitfor->clauses ) {
     432                        swtch->statements.push_back(
     433                                new CaseStmt(
     434                                        noLabels,
     435                                        new ConstantExpr( Constant::from_ulong( i++ ) ),
     436                                        {
     437                                                clause.statement,
     438                                                new BranchStmt(
     439                                                        noLabels,
     440                                                        "",
     441                                                        BranchStmt::Break
     442                                                )
     443                                        }
     444                                )
     445                        );
     446                }
     447
     448                if(waitfor->timeout.statement) {
     449                        swtch->statements.push_back(
     450                                new CaseStmt(
     451                                        noLabels,
     452                                        new ConstantExpr( Constant::from_ulong( i++ ) ),
     453                                        {
     454                                                waitfor->timeout.statement,
     455                                                new BranchStmt(
     456                                                        noLabels,
     457                                                        "",
     458                                                        BranchStmt::Break
     459                                                )
     460                                        }
     461                                )
     462                        );
     463                }
     464
     465                if(waitfor->orelse.statement) {
     466                        swtch->statements.push_back(
     467                                new CaseStmt(
     468                                        noLabels,
     469                                        new ConstantExpr( Constant::from_ulong( i++ ) ),
     470                                        {
     471                                                waitfor->orelse.statement,
     472                                                new BranchStmt(
     473                                                        noLabels,
     474                                                        "",
     475                                                        BranchStmt::Break
     476                                                )
     477                                        }
     478                                )
     479                        );
     480                }
     481
     482                stmt->push_back( swtch );
     483        }
    409484};
    410485
Note: See TracChangeset for help on using the changeset viewer.