Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    rbbe3719 re84ab3d  
    9393                ObjectDecl * addField( StructDecl * );
    9494                void addRoutines( ObjectDecl *, FunctionDecl * );
    95                 void addLockUnlockRoutines( StructDecl * );
    9695
    9796                virtual bool is_target( StructDecl * decl ) = 0;
     
    303302                void postvisit( FunctionDecl * decl );
    304303                void postvisit(   StructDecl * decl );
    305                 Statement * postmutate( MutexStmt * stmt );
    306304
    307305                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
     
    309307                void addDtorStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    310308                void addStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    311                 void addStatements( CompoundStmt * body, const std::list<Expression * > & args );
    312309                void addThreadDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args );
    313310
     
    315312                        PassVisitor< MutexKeyword > impl;
    316313                        acceptAll( translationUnit, impl );
    317                         mutateAll( translationUnit, impl );
    318314                }
    319315
     
    323319                StructDecl* dtor_guard_decl = nullptr;
    324320                StructDecl* thread_guard_decl = nullptr;
    325                 StructDecl* lock_guard_decl = nullptr;
    326321
    327322                static std::unique_ptr< Type > generic_func;
     
    465460        }
    466461
     462
    467463        void ConcurrentSueKeyword::handle( StructDecl * decl ) {
    468464                if( ! decl->body ) return;
     
    480476                FunctionDecl * func = forwardDeclare( decl );
    481477                ObjectDecl * field = addField( decl );
    482 
    483                 // add get_.* routine
    484478                addRoutines( field, func );
    485                 // add lock/unlock routines to monitors for use by mutex stmt
    486                 addLockUnlockRoutines( decl );
    487479        }
    488480
     
    617609        }
    618610
    619         // This function adds the get_.* routine body for coroutines, monitors etc
    620         //              after their corresponding struct has been made
    621611        void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) {
    622612                CompoundStmt * statement = new CompoundStmt();
     
    641631
    642632                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 );
    751633        }
    752634
     
    1052934                        assert( !thread_guard_decl );
    1053935                        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;
    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;
     936                }
    1067937        }
    1068938
     
    11881058                        ))
    11891059                );
    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) );
    12421060        }
    12431061
Note: See TracChangeset for help on using the changeset viewer.