Changeset d67cdb7 for src/Concurrency
- Timestamp:
- Sep 26, 2017, 11:27:38 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 5dc26f5
- Parents:
- 201aeb9
- Location:
- src/Concurrency
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r201aeb9 rd67cdb7 528 528 DeclarationWithType * param = decl->get_functionType()->get_parameters().front(); 529 529 auto type = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) ); 530 // if( type ) std::cerr << "FRED2" << std::endl;531 530 if( type && type->get_baseStruct()->is_thread() ) { 532 531 addStartStatement( decl, param ); -
src/Concurrency/Waitfor.cc
r201aeb9 rd67cdb7 27 27 #include "InitTweak/InitTweak.h" // for getPointerBase 28 28 #include "Parser/LinkageSpec.h" // for Cforall 29 #include " SymTab/AddVisit.h" // for acceptAndAdd29 #include "ResolvExpr/Resolver.h" // for findVoidExpression 30 30 #include "SynTree/Constant.h" // for Constant 31 31 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl … … 112 112 //============================================================================================= 113 113 114 class GenerateWaitForPass final : public With StmtsToAdd{114 class GenerateWaitForPass final : public WithIndexer { 115 115 public: 116 116 … … 126 126 127 127 ObjectDecl * declare( unsigned long count, CompoundStmt * stmt ); 128 ObjectDecl * declareFlag( CompoundStmt * stmt ); 129 Statement * makeSetter( ObjectDecl * flag ); 128 130 ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ); 129 void init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );130 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );131 Expression * call( );132 void choose();131 void init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * settter, CompoundStmt * stmt ); 132 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, Statement * settter, CompoundStmt * stmt ); 133 Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt); 134 void choose( WaitForStmt * waitfor, Expression * result, CompoundStmt * stmt ); 133 135 134 136 static void implement( std::list< Declaration * > & translationUnit ) { … … 140 142 private: 141 143 FunctionDecl * decl_waitfor = nullptr; 144 StructDecl * decl_mask = nullptr; 142 145 StructDecl * decl_acceptable = nullptr; 143 146 StructDecl * decl_monitor = nullptr; 144 DeclarationWithType * decl_m_func = nullptr;145 DeclarationWithType * decl_m_count = nullptr;146 DeclarationWithType * decl_m_monitors = nullptr;147 DeclarationWithType * decl_m_isdtor = nullptr;148 147 149 148 static std::unique_ptr< Type > generic_func; 150 149 150 UniqueName namer_acc = "__acceptables_"s; 151 UniqueName namer_idx = "__index_"s; 152 UniqueName namer_flg = "__do_run_"s; 153 UniqueName namer_msk = "__mask_"s; 151 154 UniqueName namer_mon = "__monitors_"s; 152 UniqueName namer_acc = "__acceptables_"s;153 155 UniqueName namer_tim = "__timeout_"s; 154 156 }; … … 167 169 namespace { 168 170 Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) { 169 return new ApplicationExpr(171 return new UntypedExpr( 170 172 new NameExpr( "?[?]" ), 171 173 { … … 177 179 178 180 Expression * makeOpAssign( Expression * lhs, Expression * rhs ) { 179 return new ApplicationExpr(181 return new UntypedExpr( 180 182 new NameExpr( "?=?" ), 181 183 { lhs, rhs } … … 183 185 } 184 186 185 Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) { 186 return new MemberExpr( mem, sue ); 187 } 188 189 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) { 190 return new ExprStmt( 191 noLabels, 192 makeOpAssign( 193 makeOpMember( 194 makeOpIndex( 195 object, 196 index 197 ), 198 member 187 Expression * makeOpMember( Expression * sue, const std::string & mem ) { 188 return new UntypedMemberExpr( new NameExpr( mem ), sue ); 189 } 190 191 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) { 192 std::unique_ptr< Expression > expr( makeOpAssign( 193 makeOpMember( 194 makeOpIndex( 195 object, 196 index 199 197 ), 200 value 201 ) 202 ); 198 member 199 ), 200 value 201 ) ); 202 203 return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) ); 203 204 } 204 205 … … 208 209 return new ConstantExpr( Constant::from_bool( ifnull ) ); 209 210 } 211 212 VariableExpr * extractVariable( Expression * func ) { 213 if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) { 214 return var; 215 } 216 217 CastExpr * cast = strict_dynamic_cast< CastExpr * >( func ); 218 return strict_dynamic_cast< VariableExpr * >( cast->arg ); 219 } 220 221 Expression * detectIsDtor( Expression * func ) { 222 VariableExpr * typed_func = extractVariable( func ); 223 bool is_dtor = InitTweak::isDestructor( typed_func->var ); 224 return new ConstantExpr( Constant::from_bool( is_dtor ) ); 225 } 210 226 }; 211 227 … … 216 232 217 233 void GenerateWaitForPass::premutate( FunctionDecl * decl) { 218 if( decl->name != "__ accept_internal" ) return;234 if( decl->name != "__waitfor_internal" ) return; 219 235 220 236 decl_waitfor = decl; … … 227 243 assert( !decl_acceptable ); 228 244 decl_acceptable = decl; 229 for( Declaration * field : decl_acceptable->members ) { 230 if( field->name == "func" ) decl_m_func = strict_dynamic_cast< DeclarationWithType * >( field ); 231 else if( field->name == "count" ) decl_m_count = strict_dynamic_cast< DeclarationWithType * >( field ); 232 else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field ); 233 else if( field->name == "is_dtor" ) decl_m_isdtor = strict_dynamic_cast< DeclarationWithType * >( field ); 234 } 235 245 } 246 else if( decl->name == "__waitfor_mask_t" ) { 247 assert( !decl_mask ); 248 decl_mask = decl; 236 249 } 237 250 else if( decl->name == "monitor_desc" ) { … … 242 255 243 256 Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) { 244 return waitfor; 245 246 if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 257 if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 247 258 248 259 CompoundStmt * stmt = new CompoundStmt( noLabels ); 249 260 250 261 ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt ); 262 ObjectDecl * flag = declareFlag( stmt ); 263 Statement * setter = makeSetter( flag ); 251 264 252 265 int index = 0; 253 266 for( auto & clause : waitfor->clauses ) { 254 init( acceptables, index, clause, s tmt );267 init( acceptables, index, clause, setter, stmt ); 255 268 256 269 index++; … … 262 275 waitfor->orelse .statement, 263 276 waitfor->orelse .condition, 277 setter, 264 278 stmt 265 279 ); 266 280 267 // Expression * result = call( acceptables, timeout, orelse, stmt ); 268 269 // choose( waitfor, result ); 281 CompoundStmt * compound = new CompoundStmt( noLabels ); 282 stmt->push_back( new IfStmt( 283 noLabels, 284 safeCond( new VariableExpr( flag ) ), 285 compound, 286 nullptr 287 )); 288 289 Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound ); 290 291 choose( waitfor, result, compound ); 270 292 271 293 return stmt; … … 274 296 ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt ) 275 297 { 276 ObjectDecl * acceptables = new ObjectDecl(298 ObjectDecl * acceptables = ObjectDecl::newObject( 277 299 namer_acc.newName(), 278 noStorage,279 LinkageSpec::Cforall,280 nullptr,281 300 new ArrayType( 282 301 noQualifiers, … … 294 313 stmt->push_back( new DeclStmt( noLabels, acceptables) ); 295 314 315 UntypedExpr * set = new UntypedExpr( 316 new NameExpr( "__builtin_memset" ), 317 { 318 new VariableExpr( acceptables ), 319 new ConstantExpr( Constant::from_int( 0 ) ), 320 new SizeofExpr( new VariableExpr( acceptables ) ) 321 } 322 ); 323 324 Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer ); 325 delete set; 326 327 stmt->push_back( new ExprStmt( noLabels, resolved_set ) ); 328 296 329 return acceptables; 297 330 } 298 331 332 ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) { 333 ObjectDecl * flag = ObjectDecl::newObject( 334 namer_flg.newName(), 335 new BasicType( 336 noQualifiers, 337 BasicType::Bool 338 ), 339 new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) ) 340 ); 341 342 stmt->push_back( new DeclStmt( noLabels, flag) ); 343 344 return flag; 345 } 346 347 Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) { 348 Expression * untyped = new UntypedExpr( 349 new NameExpr( "?=?" ), 350 { 351 new VariableExpr( flag ), 352 new ConstantExpr( Constant::from_ulong( 1 ) ) 353 } 354 ); 355 356 Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer ); 357 delete untyped; 358 359 return new ExprStmt( noLabels, expr ); 360 } 361 299 362 ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) { 300 363 301 ObjectDecl * mon = new ObjectDecl(364 ObjectDecl * mon = ObjectDecl::newObject( 302 365 namer_mon.newName(), 303 noStorage,304 LinkageSpec::Cforall,305 nullptr,306 366 new ArrayType( 307 367 noQualifiers, 308 new StructInstType(368 new PointerType( 309 369 noQualifiers, 310 decl_monitor 370 new StructInstType( 371 noQualifiers, 372 decl_monitor 373 ) 311 374 ), 312 375 new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), … … 316 379 new ListInit( 317 380 map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){ 318 return new SingleInit( expr ); 381 Expression * untyped = new CastExpr( 382 new UntypedExpr( 383 new NameExpr( "get_monitor" ), 384 { expr } 385 ), 386 new PointerType( 387 noQualifiers, 388 new StructInstType( 389 noQualifiers, 390 decl_monitor 391 ) 392 ) 393 ); 394 395 Expression * init = ResolvExpr::findSingleExpression( untyped, indexer ); 396 delete untyped; 397 return new SingleInit( init ); 319 398 }) 320 399 ) … … 326 405 } 327 406 328 void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {407 void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) { 329 408 330 409 ObjectDecl * monitors = declMon( clause, stmt ); 331 410 332 CompoundStmt * compound = new CompoundStmt( noLabels ); 333 compound->push_back( makeAccStatement( acceptables, index, decl_m_func , clause.target.function ) ); 334 compound->push_back( makeAccStatement( acceptables, index, decl_m_count , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) ); 335 compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) ); 336 compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor , new ConstantExpr( Constant::from_bool( true ) ) ) ); 411 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) ); 337 412 338 413 stmt->push_back( new IfStmt( 339 414 noLabels, 340 415 safeCond( clause.condition ), 341 compound, 416 new CompoundStmt({ 417 makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function ) , indexer ), 418 makeAccStatement( acceptables, index, "func" , new CastExpr( clause.target.function, fptr_t ) , indexer ), 419 makeAccStatement( acceptables, index, "list" , new VariableExpr( monitors ) , indexer ), 420 makeAccStatement( acceptables, index, "size" , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ), 421 setter->clone() 422 }), 342 423 nullptr 343 424 )); … … 353 434 bool has_else, 354 435 Expression *& else_cond, 436 Statement * setter, 355 437 CompoundStmt * stmt 356 438 ) { 357 ObjectDecl * timeout = new ObjectDecl(439 ObjectDecl * timeout = ObjectDecl::newObject( 358 440 namer_tim.newName(), 359 noStorage,360 LinkageSpec::Cforall,361 nullptr,362 441 new BasicType( 363 442 noQualifiers, … … 374 453 stmt->push_back( new IfStmt( 375 454 noLabels, 376 safeCond( else_cond ), 377 new ExprStmt( 378 noLabels, 379 makeOpAssign( 380 new VariableExpr( timeout ), 381 time 382 ) 383 ), 455 safeCond( time_cond ), 456 new CompoundStmt({ 457 new ExprStmt( 458 noLabels, 459 makeOpAssign( 460 new VariableExpr( timeout ), 461 time 462 ) 463 ), 464 setter->clone() 465 }), 384 466 nullptr 385 467 )); … … 392 474 noLabels, 393 475 safeCond( else_cond ), 394 new ExprStmt( 395 noLabels, 396 makeOpAssign( 397 new VariableExpr( timeout ), 398 new ConstantExpr( Constant::from_ulong( 0 ) ) 399 ) 400 ), 476 new CompoundStmt({ 477 new ExprStmt( 478 noLabels, 479 makeOpAssign( 480 new VariableExpr( timeout ), 481 new ConstantExpr( Constant::from_ulong( 0 ) ) 482 ) 483 ), 484 setter->clone() 485 }), 401 486 nullptr 402 487 )); … … 405 490 } 406 491 492 delete setter; 493 407 494 return new VariableExpr( timeout ); 495 } 496 497 Expression * GenerateWaitForPass::call( 498 size_t count, 499 ObjectDecl * acceptables, 500 Expression * timeout, 501 CompoundStmt * stmt 502 ) { 503 ObjectDecl * index = ObjectDecl::newObject( 504 namer_idx.newName(), 505 new BasicType( 506 noQualifiers, 507 BasicType::ShortSignedInt 508 ), 509 new SingleInit( 510 new ConstantExpr( Constant::from_int( -1 ) ) 511 ) 512 ); 513 514 stmt->push_back( new DeclStmt( noLabels, index ) ); 515 516 ObjectDecl * mask = ObjectDecl::newObject( 517 namer_msk.newName(), 518 new StructInstType( 519 noQualifiers, 520 decl_mask 521 ), 522 new ListInit({ 523 new SingleInit( new AddressExpr( new VariableExpr( index ) ) ), 524 new SingleInit( new VariableExpr( acceptables ) ), 525 new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) ) 526 }) 527 ); 528 529 stmt->push_back( new DeclStmt( noLabels, mask ) ); 530 531 stmt->push_back( new ExprStmt( 532 noLabels, 533 new ApplicationExpr( 534 VariableExpr::functionPointer( decl_waitfor ), 535 { 536 new CastExpr( 537 new VariableExpr( mask ), 538 new ReferenceType( 539 noQualifiers, 540 new StructInstType( 541 noQualifiers, 542 decl_mask 543 ) 544 ) 545 ), 546 timeout 547 } 548 ) 549 )); 550 551 return new VariableExpr( index ); 552 } 553 554 void GenerateWaitForPass::choose( 555 WaitForStmt * waitfor, 556 Expression * result, 557 CompoundStmt * stmt 558 ) { 559 SwitchStmt * swtch = new SwitchStmt( 560 noLabels, 561 result, 562 std::list<Statement *>() 563 ); 564 565 unsigned long i = 0; 566 for( auto & clause : waitfor->clauses ) { 567 swtch->statements.push_back( 568 new CaseStmt( 569 noLabels, 570 new ConstantExpr( Constant::from_ulong( i++ ) ), 571 { 572 clause.statement, 573 new BranchStmt( 574 noLabels, 575 "", 576 BranchStmt::Break 577 ) 578 } 579 ) 580 ); 581 } 582 583 if(waitfor->timeout.statement) { 584 swtch->statements.push_back( 585 new CaseStmt( 586 noLabels, 587 new ConstantExpr( Constant::from_int( -2 ) ), 588 { 589 waitfor->timeout.statement, 590 new BranchStmt( 591 noLabels, 592 "", 593 BranchStmt::Break 594 ) 595 } 596 ) 597 ); 598 } 599 600 if(waitfor->orelse.statement) { 601 swtch->statements.push_back( 602 new CaseStmt( 603 noLabels, 604 new ConstantExpr( Constant::from_int( -1 ) ), 605 { 606 waitfor->orelse.statement, 607 new BranchStmt( 608 noLabels, 609 "", 610 BranchStmt::Break 611 ) 612 } 613 ) 614 ); 615 } 616 617 stmt->push_back( swtch ); 408 618 } 409 619 };
Note: See TracChangeset
for help on using the changeset viewer.