Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    re84ab3d rbbe3719  
    9393                ObjectDecl * addField( StructDecl * );
    9494                void addRoutines( ObjectDecl *, FunctionDecl * );
     95                void addLockUnlockRoutines( StructDecl * );
    9596
    9697                virtual bool is_target( StructDecl * decl ) = 0;
     
    302303                void postvisit( FunctionDecl * decl );
    303304                void postvisit(   StructDecl * decl );
     305                Statement * postmutate( MutexStmt * stmt );
    304306
    305307                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
     
    307309                void addDtorStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    308310                void addStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
     311                void addStatements( CompoundStmt * body, const std::list<Expression * > & args );
    309312                void addThreadDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args );
    310313
     
    312315                        PassVisitor< MutexKeyword > impl;
    313316                        acceptAll( translationUnit, impl );
     317                        mutateAll( translationUnit, impl );
    314318                }
    315319
     
    319323                StructDecl* dtor_guard_decl = nullptr;
    320324                StructDecl* thread_guard_decl = nullptr;
     325                StructDecl* lock_guard_decl = nullptr;
    321326
    322327                static std::unique_ptr< Type > generic_func;
     
    460465        }
    461466
    462 
    463467        void ConcurrentSueKeyword::handle( StructDecl * decl ) {
    464468                if( ! decl->body ) return;
     
    476480                FunctionDecl * func = forwardDeclare( decl );
    477481                ObjectDecl * field = addField( decl );
     482
     483                // add get_.* routine
    478484                addRoutines( field, func );
     485                // add lock/unlock routines to monitors for use by mutex stmt
     486                addLockUnlockRoutines( decl );
    479487        }
    480488
     
    609617        }
    610618
     619        // This function adds the get_.* routine body for coroutines, monitors etc
     620        //              after their corresponding struct has been made
    611621        void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) {
    612622                CompoundStmt * statement = new CompoundStmt();
     
    631641
    632642                declsToAddAfter.push_back( get_decl );
     643        }
     644
     645        // Generates lock/unlock routines for monitors to be used by mutex stmts
     646        void ConcurrentSueKeyword::addLockUnlockRoutines( StructDecl * decl ) {
     647                // this routine will be called for all ConcurrentSueKeyword children so only continue if we are a monitor
     648                if ( !decl->is_monitor() ) return;
     649
     650                FunctionType * lock_fn_type = new FunctionType( noQualifiers, false );
     651                FunctionType * unlock_fn_type = new FunctionType( noQualifiers, false );
     652
     653                // create this ptr parameter for both routines
     654                ObjectDecl * this_decl = new ObjectDecl(
     655                        "this",
     656                        noStorageClasses,
     657                        LinkageSpec::Cforall,
     658                        nullptr,
     659                        new ReferenceType(
     660                                noQualifiers,
     661                                new StructInstType(
     662                                        noQualifiers,
     663                                        decl
     664                                )
     665                        ),
     666                        nullptr
     667                );
     668
     669                lock_fn_type->get_parameters().push_back( this_decl->clone() );
     670                unlock_fn_type->get_parameters().push_back( this_decl->clone() );
     671                fixupGenerics(lock_fn_type, decl);
     672                fixupGenerics(unlock_fn_type, decl);
     673
     674                delete this_decl;
     675
     676
     677                //////////////////////////////////////////////////////////////////////
     678                // The following generates this lock routine for all monitors
     679                /*
     680                        void lock (monitor_t & this) {
     681                                lock(get_monitor(this));
     682                        }       
     683                */
     684                FunctionDecl * lock_decl = new FunctionDecl(
     685                        "lock",
     686                        Type::Static,
     687                        LinkageSpec::Cforall,
     688                        lock_fn_type,
     689                        nullptr,
     690                        { },
     691                        Type::Inline
     692                );
     693
     694                UntypedExpr * get_monitor_lock =  new UntypedExpr (
     695                        new NameExpr( "get_monitor" ),
     696                        { new VariableExpr( lock_fn_type->get_parameters().front() ) }
     697                );
     698
     699                CompoundStmt * lock_statement = new CompoundStmt();
     700                lock_statement->push_back(
     701                        new ExprStmt(
     702                                new UntypedExpr (
     703                                        new NameExpr( "lock" ),
     704                                        {
     705                                                get_monitor_lock
     706                                        }
     707                                )
     708                        )
     709                );
     710                lock_decl->set_statements( lock_statement );
     711
     712                //////////////////////////////////////////////////////////////////
     713                // The following generates this routine for all monitors
     714                /*
     715                        void unlock (monitor_t & this) {
     716                                unlock(get_monitor(this));
     717                        }       
     718                */
     719                FunctionDecl * unlock_decl = new FunctionDecl(
     720                        "unlock",
     721                        Type::Static,
     722                        LinkageSpec::Cforall,
     723                        unlock_fn_type,
     724                        nullptr,
     725                        { },
     726                        Type::Inline
     727                );
     728
     729                CompoundStmt * unlock_statement = new CompoundStmt();
     730
     731                UntypedExpr * get_monitor_unlock =  new UntypedExpr (
     732                        new NameExpr( "get_monitor" ),
     733                        { new VariableExpr( unlock_fn_type->get_parameters().front() ) }
     734                );
     735
     736                unlock_statement->push_back(
     737                        new ExprStmt(
     738                                new UntypedExpr(
     739                                        new NameExpr( "unlock" ),
     740                                        {
     741                                                get_monitor_unlock
     742                                        }
     743                                )
     744                        )
     745                );
     746                unlock_decl->set_statements( unlock_statement );
     747               
     748                // pushes routines to declsToAddAfter to add at a later time
     749                declsToAddAfter.push_back( lock_decl );
     750                declsToAddAfter.push_back( unlock_decl );
    633751        }
    634752
     
    9341052                        assert( !thread_guard_decl );
    9351053                        thread_guard_decl = decl;
    936                 }
     1054                }
     1055                else if ( decl->name == "__mutex_stmt_lock_guard" && decl->body ) {
     1056                        assert( !lock_guard_decl );
     1057                        lock_guard_decl = decl;
     1058                }
     1059        }
     1060
     1061        Statement * MutexKeyword::postmutate( MutexStmt * stmt ) {
     1062                std::list<Statement *> stmtsForCtor;
     1063                stmtsForCtor.push_back(stmt->stmt);
     1064                CompoundStmt * body = new CompoundStmt( stmtsForCtor );
     1065                addStatements( body, stmt->mutexObjs);
     1066                return body;
    9371067        }
    9381068
     
    10581188                        ))
    10591189                );
     1190        }
     1191
     1192        void MutexKeyword::addStatements( CompoundStmt * body, const std::list<Expression * > & args ) {
     1193                ObjectDecl * monitors = new ObjectDecl(
     1194                        "__monitors",
     1195                        noStorageClasses,
     1196                        LinkageSpec::Cforall,
     1197                        nullptr,
     1198                        new ArrayType(
     1199                                noQualifiers,
     1200                                new PointerType(
     1201                                        noQualifiers,
     1202                                        new TypeofType( noQualifiers, args.front()->clone() )
     1203                                ),
     1204                                new ConstantExpr( Constant::from_ulong( args.size() ) ),
     1205                                false,
     1206                                false
     1207                        ),
     1208                        new ListInit(
     1209                                map_range < std::list<Initializer*> > ( args, [](Expression * var ){
     1210                                        return new SingleInit( new AddressExpr( var ) );
     1211                                })
     1212                        )
     1213                );
     1214
     1215                StructInstType * lock_guard_struct = new StructInstType( noQualifiers, lock_guard_decl );
     1216                TypeExpr * lock_type_expr = new TypeExpr( new TypeofType( noQualifiers, args.front()->clone() ) );
     1217
     1218                lock_guard_struct->parameters.push_back( lock_type_expr ) ;
     1219
     1220                // in reverse order :
     1221                // monitor_guard_t __guard = { __monitors, # };
     1222                body->push_front(
     1223                        new DeclStmt( new ObjectDecl(
     1224                                "__guard",
     1225                                noStorageClasses,
     1226                                LinkageSpec::Cforall,
     1227                                nullptr,
     1228                                lock_guard_struct,
     1229                                new ListInit(
     1230                                        {
     1231                                                new SingleInit( new VariableExpr( monitors ) ),
     1232                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
     1233                                        },
     1234                                        noDesignators,
     1235                                        true
     1236                                )
     1237                        ))
     1238                );
     1239
     1240                //monitor$ * __monitors[] = { get_monitor(a), get_monitor(b) };
     1241                body->push_front( new DeclStmt( monitors) );
    10601242        }
    10611243
Note: See TracChangeset for help on using the changeset viewer.