Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r6cebfef r5b7c8b5  
    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                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 );
    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.