Ignore:
Timestamp:
Oct 2, 2017, 6:02:32 PM (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:
21b7161
Parents:
3096ec1 (diff), 617b4b2 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r3096ec1 r11a2d9b  
    196196                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
    197197                void validate( DeclarationWithType * );
     198                void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    198199                void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    199200
     
    206207                StructDecl* monitor_decl = nullptr;
    207208                StructDecl* guard_decl = nullptr;
     209                StructDecl* dtor_guard_decl = nullptr;
    208210
    209211                static std::unique_ptr< Type > generic_func;
     
    229231
    230232                void postvisit( FunctionDecl * decl );
     233                void previsit ( StructDecl   * decl );
    231234
    232235                void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
     
    236239                        acceptAll( translationUnit, impl );
    237240                }
     241
     242          private :
     243                bool thread_ctor_seen = false;
     244                StructDecl * thread_decl = nullptr;
    238245        };
    239246
     
    403410                if( mutexArgs.empty() ) return;
    404411
     412                if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl );
     413
     414                bool isDtor = CodeGen::isDestructor( decl->name );
     415
     416                if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl );
     417
    405418                for(auto arg : mutexArgs) {
    406419                        validate( arg );
     
    412425                if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    413426                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    414 
    415                 addStatments( decl, body, mutexArgs );
     427                if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
     428
     429                if( isDtor ) {
     430                        addDtorStatments( decl, body, mutexArgs );
     431                }
     432                else {
     433                        addStatments( decl, body, mutexArgs );
     434                }
    416435        }
    417436
     
    425444                        assert( !guard_decl );
    426445                        guard_decl = decl;
     446                }
     447                else if( decl->name == "monitor_dtor_guard_t" ) {
     448                        assert( !dtor_guard_decl );
     449                        dtor_guard_decl = decl;
    427450                }
    428451        }
     
    457480                //Make sure that typed isn't mutex
    458481                if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     482        }
     483
     484        void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     485                Type * arg_type = args.front()->get_type()->clone();
     486                arg_type->set_mutex( false );
     487
     488                ObjectDecl * monitors = new ObjectDecl(
     489                        "__monitor",
     490                        noStorage,
     491                        LinkageSpec::Cforall,
     492                        nullptr,
     493                        new PointerType(
     494                                noQualifiers,
     495                                new StructInstType(
     496                                        noQualifiers,
     497                                        monitor_decl
     498                                )
     499                        ),
     500                        new SingleInit( new UntypedExpr(
     501                                new NameExpr( "get_monitor" ),
     502                                {  new CastExpr( new VariableExpr( args.front() ), arg_type ) }
     503                        ))
     504                );
     505
     506                assert(generic_func);
     507
     508                //in reverse order :
     509                // monitor_guard_t __guard = { __monitors, #, func };
     510                body->push_front(
     511                        new DeclStmt( noLabels, new ObjectDecl(
     512                                "__guard",
     513                                noStorage,
     514                                LinkageSpec::Cforall,
     515                                nullptr,
     516                                new StructInstType(
     517                                        noQualifiers,
     518                                        dtor_guard_decl
     519                                ),
     520                                new ListInit(
     521                                        {
     522                                                new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),
     523                                                new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
     524                                        },
     525                                        noDesignators,
     526                                        true
     527                                )
     528                        ))
     529                );
     530
     531                //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     532                body->push_front( new DeclStmt( noLabels, monitors) );
    459533        }
    460534
     
    523597        // General entry routine
    524598        //=============================================================================================
     599        void ThreadStarter::previsit( StructDecl * decl ) {
     600                if( decl->name == "thread_desc" && decl->body ) {
     601                        assert( !thread_decl );
     602                        thread_decl = decl;
     603                }
     604        }
     605
    525606        void ThreadStarter::postvisit(FunctionDecl * decl) {
    526607                if( ! CodeGen::isConstructor(decl->name) ) return;
     608
     609                Type * typeof_this = InitTweak::getTypeofThis(decl->type);
     610                StructInstType * ctored_type = dynamic_cast< StructInstType * >( typeof_this );
     611                if( ctored_type && ctored_type->baseStruct == thread_decl ) {
     612                        thread_ctor_seen = true;
     613                }
    527614
    528615                DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
    529616                auto type  = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) );
    530617                if( type && type->get_baseStruct()->is_thread() ) {
     618                        if( !thread_decl || !thread_ctor_seen ) {
     619                                throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");
     620                        }
     621
    531622                        addStartStatement( decl, param );
    532623                }
Note: See TracChangeset for help on using the changeset viewer.