Ignore:
Timestamp:
Aug 27, 2021, 12:51:55 PM (9 months ago)
Author:
caparsons <caparson@…>
Branches:
enum, forall-pointer-decay, jacob/cs343-translation, master
Children:
1b97976
Parents:
9f5a19fa
Message:

Added support for locks as parameters to mutex stmt

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r9f5a19fa raf67ee1  
    9393                ObjectDecl * addField( StructDecl * );
    9494                void addRoutines( ObjectDecl *, FunctionDecl * );
     95                void addLockUnlockRoutines( StructDecl * );
    9596
    9697                virtual bool is_target( StructDecl * decl ) = 0;
     
    322323                StructDecl* dtor_guard_decl = nullptr;
    323324                StructDecl* thread_guard_decl = nullptr;
     325                StructDecl* lock_guard_decl = nullptr;
    324326
    325327                static std::unique_ptr< Type > generic_func;
     
    463465        }
    464466
    465 
    466467        void ConcurrentSueKeyword::handle( StructDecl * decl ) {
    467468                if( ! decl->body ) return;
     
    479480                FunctionDecl * func = forwardDeclare( decl );
    480481                ObjectDecl * field = addField( decl );
     482
     483                // add get_.* routine
    481484                addRoutines( field, func );
     485                // add lock/unlock routines to monitors for use by mutex stmt
     486                addLockUnlockRoutines( decl );
    482487        }
    483488
     
    612617        }
    613618
     619        // This function adds the get_.* routine body for coroutines, monitors etc
     620        //              after their corresponding struct has been made
    614621        void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) {
    615622                CompoundStmt * statement = new CompoundStmt();
     
    634641
    635642                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
     672                delete this_decl;
     673
     674
     675                //////////////////////////////////////////////////////////////////////
     676                // The following generates this lock routine for all monitors
     677                /*
     678                        void lock (monitor_t & this) {
     679                                lock(get_monitor(this));
     680                        }       
     681                */
     682                FunctionDecl * lock_decl = new FunctionDecl(
     683                        "lock",
     684                        Type::Static,
     685                        LinkageSpec::Cforall,
     686                        lock_fn_type,
     687                        nullptr,
     688                        { },
     689                        Type::Inline
     690                );
     691                fixupGenerics(lock_fn_type, decl);
     692
     693                UntypedExpr * get_monitor_lock =  new UntypedExpr (
     694                        new NameExpr( "get_monitor" ),
     695                        { new VariableExpr( lock_fn_type->get_parameters().front() ) }
     696                );
     697
     698                CompoundStmt * lock_statement = new CompoundStmt();
     699                lock_statement->push_back(
     700                        new ExprStmt(
     701                                new UntypedExpr (
     702                                        new NameExpr( "lock" ),
     703                                        {
     704                                                get_monitor_lock
     705                                        }
     706                                )
     707                        )
     708                );
     709                lock_decl->set_statements( lock_statement );
     710
     711                //////////////////////////////////////////////////////////////////
     712                // The following generates this routine for all monitors
     713                /*
     714                        void unlock (monitor_t & this) {
     715                                unlock(get_monitor(this));
     716                        }       
     717                */
     718                FunctionDecl * unlock_decl = new FunctionDecl(
     719                        "unlock",
     720                        Type::Static,
     721                        LinkageSpec::Cforall,
     722                        unlock_fn_type,
     723                        nullptr,
     724                        { },
     725                        Type::Inline
     726                );
     727                fixupGenerics(unlock_fn_type, decl);
     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 );
    636751        }
    637752
     
    9371052                        assert( !thread_guard_decl );
    9381053                        thread_guard_decl = decl;
     1054                }
     1055                else if ( decl->name == "__mutex_stmt_lock_guard" && decl->body ) {
     1056                        assert( !lock_guard_decl );
     1057                        lock_guard_decl = decl;
    9391058                }
    9401059        }
     
    10811200                                new PointerType(
    10821201                                        noQualifiers,
    1083                                         new StructInstType(
    1084                                                 noQualifiers,
    1085                                                 monitor_decl
    1086                                         )
     1202                                        new TypeofType( noQualifiers, args.front()->clone() )
    10871203                                ),
    10881204                                new ConstantExpr( Constant::from_ulong( args.size() ) ),
     
    10931209                                map_range < std::list<Initializer*> > ( args, [](Expression * var ){
    10941210                                        return new SingleInit( new UntypedExpr(
    1095                                                 new NameExpr( "get_monitor" ),
     1211                                                new NameExpr( "__get_pointer" ),
    10961212                                                { var }
    10971213                                        ) );
     
    10991215                        )
    11001216                );
     1217
     1218                StructInstType * lock_guard_struct = new StructInstType( noQualifiers, lock_guard_decl );
     1219                TypeExpr * lock_type_expr = new TypeExpr( new TypeofType( noQualifiers, args.front()->clone() ) );
     1220
     1221                lock_guard_struct->parameters.push_back( lock_type_expr ) ;
    11011222
    11021223                // in reverse order :
     
    11081229                                LinkageSpec::Cforall,
    11091230                                nullptr,
    1110                                 new StructInstType(
    1111                                         noQualifiers,
    1112                                         guard_decl
    1113                                 ),
     1231                                lock_guard_struct,
    11141232                                new ListInit(
    11151233                                        {
Note: See TracChangeset for help on using the changeset viewer.