- Timestamp:
- Nov 17, 2017, 10:56:16 AM (8 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:
- cdbfab0
- Parents:
- f5c3b6c (diff), b7f8cb44 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 4 added
- 1 deleted
- 55 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/Debug.h
rf5c3b6c r0fe4e62 24 24 #include "SynTree/Declaration.h" 25 25 26 /// debug codegen a translation unit 27 static inline void debugCodeGen( const std::list< Declaration * > & translationUnit, const std::string & label ) { 28 std::list< Declaration * > decls; 26 #define DEBUG 29 27 30 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) { 31 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 32 }); 28 namespace Debug { 29 /// debug codegen a translation unit 30 static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label ) { 31 #ifdef DEBUG 32 std::list< Declaration * > decls; 33 33 34 std::cerr << "======" << label << "======" << std::endl; 35 CodeGen::generate( decls, std::cerr, false, true ); 36 } // dump 34 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) { 35 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 36 }); 37 38 std::cerr << "======" << label << "======" << std::endl; 39 CodeGen::generate( decls, std::cerr, false, true ); 40 #endif 41 } // dump 42 43 static inline void treeDump( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label ) { 44 #ifdef DEBUG 45 std::list< Declaration * > decls; 46 47 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) { 48 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 49 }); 50 51 std::cerr << "======" << label << "======" << std::endl; 52 printAll( decls, std::cerr ); 53 #endif 54 } // dump 55 } 37 56 38 57 // Local Variables: // -
src/Concurrency/Keywords.cc
rf5c3b6c r0fe4e62 553 553 ), 554 554 new ListInit( 555 map_range < std::list<Initializer*> > ( args, [ this](DeclarationWithType * var ){555 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){ 556 556 Type * type = var->get_type()->clone(); 557 557 type->set_mutex( false ); -
src/InitTweak/GenInit.cc
rf5c3b6c r0fe4e62 214 214 } 215 215 // a type is managed if it appears in the map of known managed types, or if it contains any polymorphism (is a type variable or generic type containing a type variable) 216 return managedTypes.find( SymTab::Mangler::mangle ( type ) ) != managedTypes.end() || GenPoly::isPolyType( type );216 return managedTypes.find( SymTab::Mangler::mangleConcrete( type ) ) != managedTypes.end() || GenPoly::isPolyType( type ); 217 217 } 218 218 … … 232 232 Type * type = InitTweak::getPointerBase( params.front()->get_type() ); 233 233 assert( type ); 234 managedTypes.insert( SymTab::Mangler::mangle ( type ) );234 managedTypes.insert( SymTab::Mangler::mangleConcrete( type ) ); 235 235 } 236 236 } … … 242 242 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) { 243 243 if ( isManaged( field ) ) { 244 // generic parameters should not play a role in determining whether a generic type is constructed - construct all generic types, so that 245 // polymorphic constructors make generic types managed types 244 246 StructInstType inst( Type::Qualifiers(), aggregateDecl ); 245 managedTypes.insert( SymTab::Mangler::mangle ( &inst ) );247 managedTypes.insert( SymTab::Mangler::mangleConcrete( &inst ) ); 246 248 break; 247 249 } -
src/InitTweak/InitTweak.cc
rf5c3b6c r0fe4e62 99 99 class InitExpander::ExpanderImpl { 100 100 public: 101 virtual ~ExpanderImpl() = default; 101 102 virtual std::list< Expression * > next( std::list< Expression * > & indices ) = 0; 102 103 virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices ) = 0; … … 106 107 public: 107 108 InitImpl( Initializer * init ) : init( init ) {} 109 virtual ~InitImpl() = default; 108 110 109 111 virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) { … … 122 124 public: 123 125 ExprImpl( Expression * expr ) : arg( expr ) {} 124 125 ~ExprImpl() { delete arg; } 126 virtual ~ExprImpl() { delete arg; } 126 127 127 128 virtual std::list< Expression * > next( std::list< Expression * > & indices ) { -
src/ResolvExpr/AlternativeFinder.cc
rf5c3b6c r0fe4e62 22 22 #include <memory> // for allocator_traits<>::value_type 23 23 #include <utility> // for pair 24 #include <vector> // for vector 24 25 25 26 #include "Alternative.h" // for AltList, Alternative … … 333 334 tmpCost.incPoly( -tmpCost.get_polyCost() ); 334 335 if ( tmpCost != Cost::zero ) { 335 // if ( convCost != Cost::zero ) {336 336 Type *newType = formalType->clone(); 337 337 env.apply( newType ); … … 405 405 /// needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() ); 406 406 } 407 }408 409 /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,410 /// producing expression(s) in out and their total cost in cost.411 template< typename AltIterator, typename OutputIterator >412 bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) {413 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {414 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType415 std::list< Expression * > exprs;416 for ( Type * type : *tupleType ) {417 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {418 deleteAll( exprs );419 return false;420 }421 }422 *out++ = new TupleExpr( exprs );423 } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {424 // xxx - mixing default arguments with variadic??425 std::list< Expression * > exprs;426 for ( ; actualIt != actualEnd; ++actualIt ) {427 exprs.push_back( actualIt->expr->clone() );428 cost += actualIt->cost;429 }430 Expression * arg = nullptr;431 if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) {432 // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes433 // xxx - what if passing multiple arguments, last of which is ttype?434 // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below.435 arg = exprs.front();436 } else {437 arg = new TupleExpr( exprs );438 }439 assert( arg && arg->get_result() );440 if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {441 return false;442 }443 *out++ = arg;444 } else if ( actualIt != actualEnd ) {445 // both actualType and formalType are atomic (non-tuple) types - if they unify446 // then accept actual as an argument, otherwise return false (fail to instantiate argument)447 Expression * actual = actualIt->expr;448 Type * actualType = actual->get_result();449 450 PRINT(451 std::cerr << "formal type is ";452 formalType->print( std::cerr );453 std::cerr << std::endl << "actual type is ";454 actualType->print( std::cerr );455 std::cerr << std::endl;456 )457 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {458 // std::cerr << "unify failed" << std::endl;459 return false;460 }461 // move the expression from the alternative to the output iterator462 *out++ = actual;463 actualIt->expr = nullptr;464 cost += actualIt->cost;465 ++actualIt;466 } else {467 // End of actuals - Handle default values468 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {469 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( si->get_value() ) ) {470 // so far, only constant expressions are accepted as default values471 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( castExpr->get_arg() ) ) {472 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {473 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {474 *out++ = cnstexpr->clone();475 return true;476 } // if477 } // if478 } // if479 }480 } // if481 return false;482 } // if483 return true;484 }485 486 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) {487 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );488 // make sure we don't widen any existing bindings489 for ( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {490 i->allowWidening = false;491 }492 resultEnv.extractOpenVars( openVars );493 494 // flatten actuals so that each actual has an atomic (non-tuple) type495 AltList exploded;496 Tuples::explode( actuals, indexer, back_inserter( exploded ) );497 498 AltList::iterator actualExpr = exploded.begin();499 AltList::iterator actualEnd = exploded.end();500 for ( DeclarationWithType * formal : formals ) {501 // match flattened actuals with formal parameters - actuals will be grouped to match502 // with formals as appropriate503 Cost cost = Cost::zero;504 std::list< Expression * > newExprs;505 ObjectDecl * obj = strict_dynamic_cast< ObjectDecl * >( formal );506 if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {507 deleteAll( newExprs );508 return false;509 }510 // success - produce argument as a new alternative511 assert( newExprs.size() == 1 );512 out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );513 }514 if ( actualExpr != actualEnd ) {515 // there are still actuals remaining, but we've run out of formal parameters to match against516 // this is okay only if the function is variadic517 if ( ! isVarArgs ) {518 return false;519 }520 out.splice( out.end(), exploded, actualExpr, actualEnd );521 }522 return true;523 407 } 524 408 … … 675 559 } 676 560 677 template< typename OutputIterator > 678 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) { 679 OpenVarSet openVars; 680 AssertionSet resultNeed, resultHave; 681 TypeEnvironment resultEnv( func.env ); 682 makeUnifiableVars( funcType, openVars, resultNeed ); 683 resultEnv.add( funcType->get_forall() ); // add all type variables as open variables now so that those not used in the parameter list are still considered open 684 AltList instantiatedActuals; // filled by instantiate function 561 /// Gets a default value from an initializer, nullptr if not present 562 ConstantExpr* getDefaultValue( Initializer* init ) { 563 if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) { 564 if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) { 565 return dynamic_cast<ConstantExpr*>( ce->get_arg() ); 566 } 567 } 568 return nullptr; 569 } 570 571 /// State to iteratively build a match of parameter expressions to arguments 572 struct ArgPack { 573 AltList actuals; ///< Arguments included in this pack 574 TypeEnvironment env; ///< Environment for this pack 575 AssertionSet need; ///< Assertions outstanding for this pack 576 AssertionSet have; ///< Assertions found for this pack 577 OpenVarSet openVars; ///< Open variables for this pack 578 unsigned nextArg; ///< Index of next argument in arguments list 579 std::vector<Alternative> expls; ///< Exploded actuals left over from last match 580 unsigned nextExpl; ///< Index of next exploded alternative to use 581 std::vector<unsigned> tupleEls; /// Number of elements in current tuple element(s) 582 583 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 584 const OpenVarSet& openVars) 585 : actuals(), env(env), need(need), have(have), openVars(openVars), nextArg(0), 586 expls(), nextExpl(0), tupleEls() {} 587 588 /// Starts a new tuple expression 589 void beginTuple() { 590 if ( ! tupleEls.empty() ) ++tupleEls.back(); 591 tupleEls.push_back(0); 592 } 593 594 /// Ends a tuple expression, consolidating the appropriate actuals 595 void endTuple() { 596 // set up new Tuple alternative 597 std::list<Expression*> exprs; 598 Cost cost = Cost::zero; 599 600 // transfer elements into alternative 601 for (unsigned i = 0; i < tupleEls.back(); ++i) { 602 exprs.push_front( actuals.back().expr ); 603 actuals.back().expr = nullptr; 604 cost += actuals.back().cost; 605 actuals.pop_back(); 606 } 607 tupleEls.pop_back(); 608 609 // build new alternative 610 actuals.emplace_back( new TupleExpr( exprs ), this->env, cost ); 611 } 612 613 /// Clones and adds an actual, returns this 614 ArgPack& withArg( Expression* expr, Cost cost = Cost::zero ) { 615 actuals.emplace_back( expr->clone(), this->env, cost ); 616 if ( ! tupleEls.empty() ) ++tupleEls.back(); 617 return *this; 618 } 619 }; 620 621 /// Instantiates an argument to match a formal, returns false if no results left 622 bool instantiateArgument( Type* formalType, Initializer* initializer, 623 const std::vector< AlternativeFinder >& args, 624 std::vector<ArgPack>& results, std::vector<ArgPack>& nextResults, 625 const SymTab::Indexer& indexer ) { 626 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { 627 // formalType is a TupleType - group actuals into a TupleExpr 628 for ( ArgPack& result : results ) { result.beginTuple(); } 629 for ( Type* type : *tupleType ) { 630 // xxx - dropping initializer changes behaviour from previous, but seems correct 631 if ( ! instantiateArgument( type, nullptr, args, results, nextResults, indexer ) ) 632 return false; 633 } 634 for ( ArgPack& result : results ) { result.endTuple(); } 635 return true; 636 } else if ( TypeInstType* ttype = Tuples::isTtype( formalType ) ) { 637 // formalType is a ttype, consumes all remaining arguments 638 // xxx - mixing default arguments with variadic?? 639 std::vector<ArgPack> finalResults{}; /// list of completed tuples 640 // start tuples 641 for ( ArgPack& result : results ) { 642 result.beginTuple(); 643 644 // use rest of exploded tuple if present 645 while ( result.nextExpl < result.expls.size() ) { 646 const Alternative& actual = result.expls[result.nextExpl]; 647 result.env.addActual( actual.env, result.openVars ); 648 result.withArg( actual.expr ); 649 ++result.nextExpl; 650 } 651 } 652 // iterate until all results completed 653 while ( ! results.empty() ) { 654 // add another argument to results 655 for ( ArgPack& result : results ) { 656 // finish result when out of arguments 657 if ( result.nextArg >= args.size() ) { 658 Type* argType = result.actuals.back().expr->get_result(); 659 if ( result.tupleEls.back() == 1 && Tuples::isTtype( argType ) ) { 660 // the case where a ttype value is passed directly is special, e.g. for 661 // argument forwarding purposes 662 // xxx - what if passing multiple arguments, last of which is ttype? 663 // xxx - what would happen if unify was changed so that unifying tuple 664 // types flattened both before unifying lists? then pass in TupleType 665 // (ttype) below. 666 result.tupleEls.pop_back(); 667 } else { 668 // collapse leftover arguments into tuple 669 result.endTuple(); 670 argType = result.actuals.back().expr->get_result(); 671 } 672 // check unification for ttype before adding to final 673 if ( unify( ttype, argType, result.env, result.need, result.have, 674 result.openVars, indexer ) ) { 675 finalResults.push_back( std::move(result) ); 676 } 677 continue; 678 } 679 680 // add each possible next argument 681 for ( const Alternative& actual : args[result.nextArg] ) { 682 ArgPack aResult = result; // copy to clone everything 683 // add details of actual to result 684 aResult.env.addActual( actual.env, aResult.openVars ); 685 Cost cost = actual.cost; 686 687 // explode argument 688 std::vector<Alternative> exploded; 689 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 690 691 // add exploded argument to tuple 692 for ( Alternative& aActual : exploded ) { 693 aResult.withArg( aActual.expr, cost ); 694 cost = Cost::zero; 695 } 696 ++aResult.nextArg; 697 nextResults.push_back( std::move(aResult) ); 698 } 699 } 700 701 // reset for next round 702 results.swap( nextResults ); 703 nextResults.clear(); 704 } 705 results.swap( finalResults ); 706 return ! results.empty(); 707 } 708 709 // iterate each current subresult 710 for ( unsigned iResult = 0; iResult < results.size(); ++iResult ) { 711 ArgPack& result = results[iResult]; 712 713 if ( result.nextExpl < result.expls.size() ) { 714 // use remainder of exploded tuple if present 715 const Alternative& actual = result.expls[result.nextExpl]; 716 result.env.addActual( actual.env, result.openVars ); 717 Type* actualType = actual.expr->get_result(); 718 719 PRINT( 720 std::cerr << "formal type is "; 721 formalType->print( std::cerr ); 722 std::cerr << std::endl << "actual type is "; 723 actualType->print( std::cerr ); 724 std::cerr << std::endl; 725 ) 726 727 if ( unify( formalType, actualType, result.env, result.need, result.have, 728 result.openVars, indexer ) ) { 729 ++result.nextExpl; 730 nextResults.push_back( std::move(result.withArg( actual.expr )) ); 731 } 732 733 continue; 734 } else if ( result.nextArg >= args.size() ) { 735 // use default initializers if out of arguments 736 if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) { 737 if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) { 738 if ( unify( formalType, cnst->get_type(), result.env, result.need, 739 result.have, result.openVars, indexer ) ) { 740 nextResults.push_back( std::move(result.withArg( cnstExpr )) ); 741 } 742 } 743 } 744 continue; 745 } 746 747 // Check each possible next argument 748 for ( const Alternative& actual : args[result.nextArg] ) { 749 ArgPack aResult = result; // copy to clone everything 750 // add details of actual to result 751 aResult.env.addActual( actual.env, aResult.openVars ); 752 753 // explode argument 754 std::vector<Alternative> exploded; 755 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 756 if ( exploded.empty() ) { 757 // skip empty tuple arguments 758 ++aResult.nextArg; 759 results.push_back( std::move(aResult) ); 760 continue; 761 } 762 763 // consider only first exploded actual 764 const Alternative& aActual = exploded.front(); 765 Type* actualType = aActual.expr->get_result()->clone(); 766 767 PRINT( 768 std::cerr << "formal type is "; 769 formalType->print( std::cerr ); 770 std::cerr << std::endl << "actual type is "; 771 actualType->print( std::cerr ); 772 std::cerr << std::endl; 773 ) 774 775 // attempt to unify types 776 if ( unify( formalType, actualType, aResult.env, aResult.need, aResult.have, aResult.openVars, indexer ) ) { 777 // add argument 778 aResult.withArg( aActual.expr, actual.cost ); 779 ++aResult.nextArg; 780 if ( exploded.size() > 1 ) { 781 // other parts of tuple left over 782 aResult.expls = std::move( exploded ); 783 aResult.nextExpl = 1; 784 } 785 nextResults.push_back( std::move(aResult) ); 786 } 787 } 788 } 789 790 // reset for next parameter 791 results.swap( nextResults ); 792 nextResults.clear(); 793 794 return ! results.empty(); 795 } 796 797 template<typename OutputIterator> 798 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, 799 FunctionType *funcType, const std::vector< AlternativeFinder > &args, 800 OutputIterator out ) { 801 OpenVarSet funcOpenVars; 802 AssertionSet funcNeed, funcHave; 803 TypeEnvironment funcEnv( func.env ); 804 makeUnifiableVars( funcType, funcOpenVars, funcNeed ); 805 // add all type variables as open variables now so that those not used in the parameter 806 // list are still considered open. 807 funcEnv.add( funcType->get_forall() ); 808 685 809 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) { 686 810 // attempt to narrow based on expected target type 687 811 Type * returnType = funcType->get_returnVals().front()->get_type(); 688 if ( ! unify( returnType, targetType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 689 // unification failed, don't pursue this alternative 812 if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars, 813 indexer ) ) { 814 // unification failed, don't pursue this function alternative 690 815 return; 691 816 } 692 817 } 693 818 694 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 819 // iteratively build matches, one parameter at a time 820 std::vector<ArgPack> results{ ArgPack{ funcEnv, funcNeed, funcHave, funcOpenVars } }; 821 std::vector<ArgPack> nextResults{}; 822 for ( DeclarationWithType* formal : funcType->get_parameters() ) { 823 ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal ); 824 if ( ! instantiateArgument( 825 obj->get_type(), obj->get_init(), args, results, nextResults, indexer ) ) 826 return; 827 } 828 829 // filter out results that don't use all the arguments, and aren't variadic 830 std::vector<ArgPack> finalResults{}; 831 if ( funcType->get_isVarArgs() ) { 832 for ( ArgPack& result : results ) { 833 // use rest of exploded tuple if present 834 while ( result.nextExpl < result.expls.size() ) { 835 const Alternative& actual = result.expls[result.nextExpl]; 836 result.env.addActual( actual.env, result.openVars ); 837 result.withArg( actual.expr ); 838 ++result.nextExpl; 839 } 840 } 841 842 while ( ! results.empty() ) { 843 // build combinations for all remaining arguments 844 for ( ArgPack& result : results ) { 845 // keep if used all arguments 846 if ( result.nextArg >= args.size() ) { 847 finalResults.push_back( std::move(result) ); 848 continue; 849 } 850 851 // add each possible next argument 852 for ( const Alternative& actual : args[result.nextArg] ) { 853 ArgPack aResult = result; // copy to clone everything 854 // add details of actual to result 855 aResult.env.addActual( actual.env, aResult.openVars ); 856 Cost cost = actual.cost; 857 858 // explode argument 859 std::vector<Alternative> exploded; 860 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 861 862 // add exploded argument to arg list 863 for ( Alternative& aActual : exploded ) { 864 aResult.withArg( aActual.expr, cost ); 865 cost = Cost::zero; 866 } 867 ++aResult.nextArg; 868 nextResults.push_back( std::move(aResult) ); 869 } 870 } 871 872 // reset for next round 873 results.swap( nextResults ); 874 nextResults.clear(); 875 } 876 } else { 877 // filter out results that don't use all the arguments 878 for ( ArgPack& result : results ) { 879 if ( result.nextExpl >= result.expls.size() && result.nextArg >= args.size() ) { 880 finalResults.push_back( std::move(result) ); 881 } 882 } 883 } 884 885 // validate matching combos, add to final result list 886 for ( ArgPack& result : finalResults ) { 695 887 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 696 Alternative newAlt( appExpr, result Env, sumCost( instantiatedActuals ) );697 makeExprList( instantiatedActuals, appExpr->get_args() );888 Alternative newAlt( appExpr, result.env, sumCost( result.actuals ) ); 889 makeExprList( result.actuals, appExpr->get_args() ); 698 890 PRINT( 699 891 std::cerr << "instantiate function success: " << appExpr << std::endl; 700 892 std::cerr << "need assertions:" << std::endl; 701 printAssertionSet( result Need, std::cerr, 8 );893 printAssertionSet( result.need, std::cerr, 8 ); 702 894 ) 703 inferParameters( result Need, resultHave, newAlt,openVars, out );895 inferParameters( result.need, result.have, newAlt, result.openVars, out ); 704 896 } 705 897 } … … 711 903 if ( funcFinder.alternatives.empty() ) return; 712 904 713 std::list< AlternativeFinder > argAlternatives; 714 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) ); 715 716 std::list< AltList > possibilities; 717 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 905 std::vector< AlternativeFinder > argAlternatives; 906 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), 907 back_inserter( argAlternatives ) ); 718 908 719 909 // take care of possible tuple assignments 720 910 // if not tuple assignment, assignment is taken care of as a normal function call 721 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );911 Tuples::handleTupleAssignment( *this, untypedExpr, argAlternatives ); 722 912 723 913 // find function operators … … 744 934 Alternative newFunc( *func ); 745 935 referenceToRvalueConversion( newFunc.expr ); 746 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 747 // XXX 748 //Designators::check_alternative( function, *actualAlt ); 749 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) ); 750 } 936 makeFunctionAlternatives( newFunc, function, argAlternatives, 937 std::back_inserter( candidates ) ); 751 938 } 752 939 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) … … 756 943 Alternative newFunc( *func ); 757 944 referenceToRvalueConversion( newFunc.expr ); 758 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 759 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) ); 760 } // for 945 makeFunctionAlternatives( newFunc, function, argAlternatives, 946 std::back_inserter( candidates ) ); 761 947 } // if 762 948 } // if 763 949 } 764 765 // try each function operator ?() with the current function alternative and each of the argument combinations 766 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 767 // check if the type is pointer to function 768 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) { 769 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 950 } catch ( SemanticError &e ) { 951 errors.append( e ); 952 } 953 } // for 954 955 // try each function operator ?() with each function alternative 956 if ( ! funcOpFinder.alternatives.empty() ) { 957 // add function alternatives to front of argument list 958 argAlternatives.insert( argAlternatives.begin(), std::move(funcFinder) ); 959 960 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); 961 funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 962 try { 963 // check if type is a pointer to function 964 if ( PointerType* pointer = dynamic_cast<PointerType*>( 965 funcOp->expr->get_result()->stripReferences() ) ) { 966 if ( FunctionType* function = 967 dynamic_cast<FunctionType*>( pointer->get_base() ) ) { 770 968 Alternative newFunc( *funcOp ); 771 969 referenceToRvalueConversion( newFunc.expr ); 772 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 773 AltList currentAlt; 774 currentAlt.push_back( *func ); 775 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() ); 776 makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) ); 777 } // for 778 } // if 779 } // if 780 } // for 781 } catch ( SemanticError &e ) { 782 errors.append( e ); 783 } 784 } // for 970 makeFunctionAlternatives( newFunc, function, argAlternatives, 971 std::back_inserter( candidates ) ); 972 } 973 } 974 } catch ( SemanticError &e ) { 975 errors.append( e ); 976 } 977 } 978 } 785 979 786 980 // Implement SFINAE; resolution errors are only errors if there aren't any non-erroneous resolutions … … 813 1007 candidates.splice( candidates.end(), alternatives ); 814 1008 815 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) ); 1009 // use a new list so that alternatives are not examined by addAnonConversions twice. 1010 AltList winners; 1011 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) ); 816 1012 817 1013 // function may return struct or union value, in which case we need to add alternatives for implicit 818 1014 // conversions to each of the anonymous members, must happen after findMinCost since anon conversions 819 1015 // are never the cheapest expression 820 for ( const Alternative & alt : alternatives ) {1016 for ( const Alternative & alt : winners ) { 821 1017 addAnonConversions( alt ); 822 1018 } 1019 alternatives.splice( alternatives.begin(), winners ); 823 1020 824 1021 if ( alternatives.empty() && targetType && ! targetType->isVoid() ) { -
src/ResolvExpr/AlternativeFinder.h
rf5c3b6c r0fe4e62 34 34 public: 35 35 AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env ); 36 37 AlternativeFinder( const AlternativeFinder& o ) 38 : indexer(o.indexer), alternatives(o.alternatives), env(o.env), 39 targetType(o.targetType) {} 40 41 AlternativeFinder( AlternativeFinder&& o ) 42 : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env), 43 targetType(o.targetType) {} 44 45 AlternativeFinder& operator= ( const AlternativeFinder& o ) { 46 if (&o == this) return *this; 47 48 // horrific nasty hack to rebind references... 49 alternatives.~AltList(); 50 new(this) AlternativeFinder(o); 51 return *this; 52 } 53 54 AlternativeFinder& operator= ( AlternativeFinder&& o ) { 55 if (&o == this) return *this; 56 57 // horrific nasty hack to rebind references... 58 alternatives.~AltList(); 59 new(this) AlternativeFinder(std::move(o)); 60 return *this; 61 } 62 36 63 void find( Expression *expr, bool adjust = false, bool prune = true, bool failFast = true ); 37 64 /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types … … 99 126 /// Adds alternatives for offsetof expressions, given the base type and name of the member 100 127 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 101 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ); 102 template< typename OutputIterator > 103 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ); 128 template<typename OutputIterator> 129 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out ); 104 130 template< typename OutputIterator > 105 131 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); -
src/ResolvExpr/CurrentObject.cc
rf5c3b6c r0fe4e62 260 260 261 261 AggregateIterator( const std::string & kind, const std::string & name, Type * inst, const MemberList & members ) : kind( kind ), name( name ), inst( inst ), members( members ), curMember( members.begin() ), sub( makeGenericSubstitution( inst ) ) { 262 PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; ) 262 263 init(); 263 264 } -
src/ResolvExpr/RenameVars.cc
rf5c3b6c r0fe4e62 29 29 RenameVars global_renamer; 30 30 31 RenameVars::RenameVars() : level( 0 ) {31 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 32 32 mapStack.push_front( std::map< std::string, std::string >() ); 33 33 } … … 35 35 void RenameVars::reset() { 36 36 level = 0; 37 resetCount++; 37 38 } 38 39 … … 130 131 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 131 132 std::ostringstream output; 132 output << "_" << level << "_" << (*i)->get_name();133 output << "_" << resetCount << "_" << level << "_" << (*i)->get_name(); 133 134 std::string newname( output.str() ); 134 135 mapStack.front()[ (*i)->get_name() ] = newname; -
src/ResolvExpr/RenameVars.h
rf5c3b6c r0fe4e62 48 48 void typeBefore( Type *type ); 49 49 void typeAfter( Type *type ); 50 int level ;50 int level, resetCount; 51 51 std::list< std::map< std::string, std::string > > mapStack; 52 52 }; -
src/ResolvExpr/TypeEnvironment.cc
rf5c3b6c r0fe4e62 201 201 } 202 202 203 void TypeEnvironment::addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ) { 204 for ( const EqvClass& c : actualEnv ) { 205 EqvClass c2 = c; 206 c2.allowWidening = false; 207 for ( const std::string& var : c2.vars ) { 208 openVars[ var ] = c2.data; 209 } 210 env.push_back( std::move(c2) ); 211 } 212 } 213 203 214 } // namespace ResolvExpr 204 215 -
src/ResolvExpr/TypeEnvironment.h
rf5c3b6c r0fe4e62 86 86 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } 87 87 88 /// Iteratively adds the environment of a new actual (with allowWidening = false), 89 /// and extracts open variables. 90 void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ); 91 88 92 typedef std::list< EqvClass >::iterator iterator; 89 93 iterator begin() { return env.begin(); } -
src/SymTab/Mangler.cc
rf5c3b6c r0fe4e62 32 32 namespace SymTab { 33 33 std::string Mangler::mangleType( Type * ty ) { 34 Mangler mangler( false, true );34 Mangler mangler( false, true, true ); 35 35 maybeAccept( ty, mangler ); 36 36 return mangler.get_mangleName(); 37 37 } 38 38 39 Mangler::Mangler( bool mangleOverridable, bool typeMode ) 40 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {} 39 std::string Mangler::mangleConcrete( Type* ty ) { 40 Mangler mangler( false, false, false ); 41 maybeAccept( ty, mangler ); 42 return mangler.get_mangleName(); 43 } 44 45 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 46 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {} 41 47 42 48 Mangler::Mangler( const Mangler &rhs ) : mangleName() { … … 166 172 167 173 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name(); 168 } 169 170 void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) { 171 printQualifiers( refType ); 172 173 std::ostringstream oldName( mangleName.str() ); 174 mangleName.clear(); 175 176 mangleName << prefix << refType->get_name(); 177 178 std::list< Expression* >& params = refType->get_parameters(); 179 if ( ! params.empty() ) { 180 mangleName << "_"; 181 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { 182 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 183 assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str()); 184 maybeAccept( paramType->get_type(), *this ); 174 175 if ( mangleGenericParams ) { 176 std::list< Expression* >& params = refType->get_parameters(); 177 if ( ! params.empty() ) { 178 mangleName << "_"; 179 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { 180 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 181 assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str()); 182 maybeAccept( paramType->get_type(), *this ); 183 } 184 mangleName << "_"; 185 185 } 186 mangleName << "_";187 186 } 188 189 oldName << mangleName.str().length() << mangleName.str();190 mangleName.str( oldName.str() );191 187 } 192 188 193 189 void Mangler::visit( StructInstType * aggregateUseType ) { 194 if ( typeMode ) mangleGenericRef( aggregateUseType, "s" ); 195 else mangleRef( aggregateUseType, "s" ); 190 mangleRef( aggregateUseType, "s" ); 196 191 } 197 192 198 193 void Mangler::visit( UnionInstType * aggregateUseType ) { 199 if ( typeMode ) mangleGenericRef( aggregateUseType, "u" ); 200 else mangleRef( aggregateUseType, "u" ); 194 mangleRef( aggregateUseType, "u" ); 201 195 } 202 196 … … 285 279 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 286 280 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 287 Mangler sub_mangler( mangleOverridable, typeMode );281 Mangler sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); 288 282 sub_mangler.nextVarNum = nextVarNum; 289 283 sub_mangler.isTopLevel = false; -
src/SymTab/Mangler.h
rf5c3b6c r0fe4e62 30 30 /// Mangle syntax tree object; primary interface to clients 31 31 template< typename SynTreeClass > 32 static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool typeMode = false );32 static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 33 33 /// Mangle a type name; secondary interface 34 34 static std::string mangleType( Type* ty ); 35 /// Mangle ignoring generic type parameters 36 static std::string mangleConcrete( Type* ty ); 37 35 38 36 39 virtual void visit( ObjectDecl *declaration ); … … 62 65 bool mangleOverridable; ///< Specially mangle overridable built-in methods 63 66 bool typeMode; ///< Produce a unique mangled name for a type 67 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 64 68 65 Mangler( bool mangleOverridable, bool typeMode );69 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 66 70 Mangler( const Mangler & ); 67 71 68 72 void mangleDecl( DeclarationWithType *declaration ); 69 73 void mangleRef( ReferenceToType *refType, std::string prefix ); 70 void mangleGenericRef( ReferenceToType *refType, std::string prefix );71 74 72 75 void printQualifiers( Type *type ); … … 74 77 75 78 template< typename SynTreeClass > 76 std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool typeMode ) {77 Mangler mangler( mangleOverridable, typeMode );79 std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 80 Mangler mangler( mangleOverridable, typeMode, mangleGenericParams ); 78 81 maybeAccept( decl, mangler ); 79 82 return mangler.get_mangleName(); -
src/SymTab/Validate.cc
rf5c3b6c r0fe4e62 268 268 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 269 269 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 270 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling 270 271 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 271 272 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 272 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist273 273 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 274 274 ReturnChecker::checkFunctionReturns( translationUnit ); -
src/Tuples/TupleAssignment.cc
rf5c3b6c r0fe4e62 20 20 #include <memory> // for unique_ptr, allocator_trai... 21 21 #include <string> // for string 22 #include <vector> 22 23 23 24 #include "CodeGen/OperatorTable.h" … … 33 34 #include "ResolvExpr/Resolver.h" // for resolveCtorInit 34 35 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 36 #include "ResolvExpr/typeops.h" // for combos 35 37 #include "SynTree/Declaration.h" // for ObjectDecl 36 38 #include "SynTree/Expression.h" // for Expression, CastExpr, Name... … … 52 54 // dispatcher for Tuple (multiple and mass) assignment operations 53 55 TupleAssignSpotter( ResolvExpr::AlternativeFinder & ); 54 void spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities );56 void spot( UntypedExpr * expr, std::vector<ResolvExpr::AlternativeFinder> &args ); 55 57 56 58 private: … … 59 61 struct Matcher { 60 62 public: 61 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 63 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 64 ResolvExpr::AltList& rhs ); 62 65 virtual ~Matcher() {} 63 66 virtual void match( std::list< Expression * > &out ) = 0; … … 72 75 struct MassAssignMatcher : public Matcher { 73 76 public: 74 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 77 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 78 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 75 79 virtual void match( std::list< Expression * > &out ); 76 80 }; … … 78 82 struct MultipleAssignMatcher : public Matcher { 79 83 public: 80 MultipleAssignMatcher( TupleAssignSpotter &spot, const ResolvExpr::AltList & alts ); 84 MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 85 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 81 86 virtual void match( std::list< Expression * > &out ); 82 87 }; … … 114 119 } 115 120 116 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 121 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 122 std::vector<ResolvExpr::AlternativeFinder> &args ) { 117 123 TupleAssignSpotter spotter( currentFinder ); 118 spotter.spot( expr, possibilities );124 spotter.spot( expr, args ); 119 125 } 120 126 … … 122 128 : currentFinder(f) {} 123 129 124 void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 130 void TupleAssignSpotter::spot( UntypedExpr * expr, 131 std::vector<ResolvExpr::AlternativeFinder> &args ) { 125 132 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 126 133 if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) { 127 fname = op->get_name(); 128 PRINT( std::cerr << "TupleAssignment: " << fname << std::endl; ) 129 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 130 if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal 131 if ( ali->size() <= 1 && CodeGen::isAssignment( op->get_name() ) ) { 132 // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it 133 continue; 134 fname = op->get_name(); 135 136 // AlternativeFinder will naturally handle this case case, if it's legal 137 if ( args.size() == 0 ) return; 138 139 // if an assignment only takes 1 argument, that's odd, but maybe someone wrote 140 // the function, in which case AlternativeFinder will handle it normally 141 if ( args.size() == 1 && CodeGen::isAssignment( fname ) ) return; 142 143 // look over all possible left-hand-sides 144 for ( ResolvExpr::Alternative& lhsAlt : args[0] ) { 145 // skip non-tuple LHS 146 if ( ! refToTuple(lhsAlt.expr) ) continue; 147 148 // explode is aware of casts - ensure every LHS expression is sent into explode 149 // with a reference cast 150 // xxx - this seems to change the alternatives before the normal 151 // AlternativeFinder flow; maybe this is desired? 152 if ( ! dynamic_cast<CastExpr*>( lhsAlt.expr ) ) { 153 lhsAlt.expr = new CastExpr( lhsAlt.expr, 154 new ReferenceType( Type::Qualifiers(), 155 lhsAlt.expr->get_result()->clone() ) ); 134 156 } 135 157 136 assert( ! ali->empty() ); 137 // grab args 2-N and group into a TupleExpr 138 const ResolvExpr::Alternative & alt1 = ali->front(); 139 auto begin = std::next(ali->begin(), 1), end = ali->end(); 140 PRINT( std::cerr << "alt1 is " << alt1.expr << std::endl; ) 141 if ( refToTuple(alt1.expr) ) { 142 PRINT( std::cerr << "and is reference to tuple" << std::endl; ) 143 if ( isMultAssign( begin, end ) ) { 144 PRINT( std::cerr << "possible multiple assignment" << std::endl; ) 145 matcher.reset( new MultipleAssignMatcher( *this, *ali ) ); 146 } else { 147 // mass assignment 148 PRINT( std::cerr << "possible mass assignment" << std::endl; ) 149 matcher.reset( new MassAssignMatcher( *this, *ali ) ); 158 // explode the LHS so that each field of a tuple-valued-expr is assigned 159 ResolvExpr::AltList lhs; 160 explode( lhsAlt, currentFinder.get_indexer(), back_inserter(lhs), true ); 161 for ( ResolvExpr::Alternative& alt : lhs ) { 162 // each LHS value must be a reference - some come in with a cast expression, 163 // if not just cast to reference here 164 if ( ! dynamic_cast<ReferenceType*>( alt.expr->get_result() ) ) { 165 alt.expr = new CastExpr( alt.expr, 166 new ReferenceType( Type::Qualifiers(), 167 alt.expr->get_result()->clone() ) ); 150 168 } 169 } 170 171 if ( args.size() == 1 ) { 172 // mass default-initialization/destruction 173 ResolvExpr::AltList rhs{}; 174 matcher.reset( new MassAssignMatcher( *this, lhs, rhs ) ); 151 175 match(); 176 } else if ( args.size() > 2 ) { 177 // expand all possible RHS possibilities 178 // TODO build iterative version of this instead of using combos 179 std::vector< ResolvExpr::AltList > rhsAlts; 180 combos( std::next(args.begin(), 1), args.end(), 181 std::back_inserter( rhsAlts ) ); 182 for ( const ResolvExpr::AltList& rhsAlt : rhsAlts ) { 183 // multiple assignment 184 ResolvExpr::AltList rhs; 185 explode( rhsAlt, currentFinder.get_indexer(), 186 std::back_inserter(rhs), true ); 187 matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) ); 188 match(); 189 } 190 } else { 191 for ( const ResolvExpr::Alternative& rhsAlt : args[1] ) { 192 ResolvExpr::AltList rhs; 193 if ( isTuple(rhsAlt.expr) ) { 194 // multiple assignment 195 explode( rhsAlt, currentFinder.get_indexer(), 196 std::back_inserter(rhs), true ); 197 matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) ); 198 } else { 199 // mass assignment 200 rhs.push_back( rhsAlt ); 201 matcher.reset( new MassAssignMatcher( *this, lhs, rhs ) ); 202 } 203 match(); 204 } 152 205 } 153 206 } … … 169 222 ResolvExpr::AltList current; 170 223 // now resolve new assignments 171 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 224 for ( std::list< Expression * >::iterator i = new_assigns.begin(); 225 i != new_assigns.end(); ++i ) { 172 226 PRINT( 173 227 std::cerr << "== resolving tuple assign ==" << std::endl; … … 175 229 ) 176 230 177 ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() ); 231 ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 232 currentFinder.get_environ() }; 178 233 try { 179 234 finder.findWithAdjustment(*i); … … 196 251 // combine assignment environments into combined expression environment 197 252 simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv ); 198 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 199 } 200 201 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter), baseCost( ResolvExpr::sumCost( alts ) ) { 202 assert( ! alts.empty() ); 203 // combine argument environments into combined expression environment 204 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 205 206 ResolvExpr::Alternative lhsAlt = alts.front(); 207 // explode is aware of casts - ensure every LHS expression is sent into explode with a reference cast 208 if ( ! dynamic_cast< CastExpr * >( lhsAlt.expr ) ) { 209 lhsAlt.expr = new CastExpr( lhsAlt.expr, new ReferenceType( Type::Qualifiers(), lhsAlt.expr->get_result()->clone() ) ); 210 } 211 212 // explode the lhs so that each field of the tuple-valued-expr is assigned. 213 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs), true ); 214 215 for ( ResolvExpr::Alternative & alt : lhs ) { 216 // every LHS value must be a reference - some come in with a cast expression, if it doesn't just cast to reference here. 217 if ( ! dynamic_cast< ReferenceType * >( alt.expr->get_result() ) ) { 218 alt.expr = new CastExpr( alt.expr, new ReferenceType( Type::Qualifiers(), alt.expr->get_result()->clone() ) ); 219 } 220 } 221 } 222 223 TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 224 assert( alts.size() == 1 || alts.size() == 2 ); 225 if ( alts.size() == 2 ) { 226 rhs.push_back( alts.back() ); 227 } 228 } 229 230 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 231 // explode the rhs so that each field of the tuple-valued-expr is assigned. 232 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs), true ); 253 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative( 254 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 255 ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 256 } 257 258 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 259 const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 260 : lhs(lhs), rhs(rhs), spotter(spotter), 261 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 262 simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv ); 263 simpleCombineEnvironments( rhs.begin(), rhs.end(), compositeEnv ); 233 264 } 234 265 -
src/Tuples/Tuples.h
rf5c3b6c r0fe4e62 17 17 18 18 #include <string> 19 #include <vector> 19 20 20 21 #include "SynTree/Expression.h" … … 26 27 namespace Tuples { 27 28 // TupleAssignment.cc 28 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, const std::list<ResolvExpr::AltList> & possibilities ); 29 29 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 30 std::vector< ResolvExpr::AlternativeFinder >& args ); 31 30 32 // TupleExpansion.cc 31 33 /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate -
src/benchmark/Makefile.am
rf5c3b6c r0fe4e62 23 23 STATS = ${TOOLSDIR}stat.py 24 24 repeats = 30 25 TIME_FORMAT = "%E" 26 PRINT_FORMAT = '%20s\t' 25 27 26 28 .NOTPARALLEL: … … 28 30 noinst_PROGRAMS = 29 31 30 bench$(EXEEXT) : 31 @for ccflags in "-debug" "-nodebug"; do \ 32 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\ 33 ${CC} ${AM_CFLAGS} ${CFLAGS} $${ccflags} -lrt bench.c;\ 34 ./a.out ; \ 35 done ; \ 36 rm -f ./a.out ; 37 38 csv-data$(EXEEXT): 39 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=50000000 csv-data.c 40 @./a.out 41 @rm -f ./a.out 42 43 ## ========================================================================================================= 44 ctxswitch$(EXEEXT): \ 45 ctxswitch-pthread.run \ 46 ctxswitch-cfa_coroutine.run \ 47 ctxswitch-cfa_thread.run \ 48 ctxswitch-upp_coroutine.run \ 49 ctxswitch-upp_thread.run 50 51 ctxswitch-cfa_coroutine$(EXEEXT): 52 ${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 53 54 ctxswitch-cfa_thread$(EXEEXT): 55 ${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 56 57 ctxswitch-upp_coroutine$(EXEEXT): 58 u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 59 60 ctxswitch-upp_thread$(EXEEXT): 61 u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 62 63 ctxswitch-pthread$(EXEEXT): 64 @BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 65 66 ## ========================================================================================================= 67 creation$(EXEEXT) :\ 68 creation-pthread.run \ 69 creation-cfa_coroutine.run \ 70 creation-cfa_thread.run \ 71 creation-upp_coroutine.run \ 72 creation-upp_thread.run 73 74 creation-cfa_coroutine$(EXEEXT): 75 ${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 76 77 creation-cfa_thread$(EXEEXT): 78 ${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 79 80 creation-upp_coroutine$(EXEEXT): 81 u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 82 83 creation-upp_thread$(EXEEXT): 84 u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 85 86 creation-pthread$(EXEEXT): 87 @BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 88 89 ## ========================================================================================================= 90 mutex$(EXEEXT) :\ 91 mutex-function.run \ 92 mutex-pthread_lock.run \ 93 mutex-upp.run \ 94 mutex-cfa1.run \ 95 mutex-cfa2.run \ 96 mutex-cfa4.run 97 98 mutex-function$(EXEEXT): 99 @BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 100 101 mutex-pthread_lock$(EXEEXT): 102 @BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 103 104 mutex-upp$(EXEEXT): 105 u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 106 107 mutex-cfa1$(EXEEXT): 108 ${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 109 110 mutex-cfa2$(EXEEXT): 111 ${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 112 113 mutex-cfa4$(EXEEXT): 114 ${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 115 116 ## ========================================================================================================= 117 signal$(EXEEXT) :\ 118 signal-upp.run \ 119 signal-cfa1.run \ 120 signal-cfa2.run \ 121 signal-cfa4.run 122 123 signal-upp$(EXEEXT): 124 u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 125 126 signal-cfa1$(EXEEXT): 127 ${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 128 129 signal-cfa2$(EXEEXT): 130 ${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 131 132 signal-cfa4$(EXEEXT): 133 ${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 134 135 ## ========================================================================================================= 136 waitfor$(EXEEXT) :\ 137 waitfor-upp.run \ 138 waitfor-cfa1.run \ 139 waitfor-cfa2.run \ 140 waitfor-cfa4.run 141 142 waitfor-upp$(EXEEXT): 143 u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 144 145 waitfor-cfa1$(EXEEXT): 146 ${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 147 148 waitfor-cfa2$(EXEEXT): 149 ${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 150 151 waitfor-cfa4$(EXEEXT): 152 ${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 153 154 ## ========================================================================================================= 32 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT) 155 33 156 34 %.run : %$(EXEEXT) ${REPEAT} … … 163 41 @rm -f a.out .result.log 164 42 43 %.runquiet : 44 @+make $(basename $@) 45 @./a.out 46 @rm -f a.out 47 48 %.make : 49 @printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@)) 50 @+/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1 51 165 52 ${REPEAT} : 166 53 @+make -C ${TOOLSDIR} repeat 54 55 ## ========================================================================================================= 56 57 jenkins$(EXEEXT): 58 @echo "{" 59 @echo -e '\t"githash": "'${githash}'",' 60 @echo -e '\t"arch": "' ${arch} '",' 61 @echo -e '\t"compile": {' 62 @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :' 63 @echo -e '\t\t"dummy" : {}' 64 @echo -e '\t},' 65 @echo -e '\t"ctxswitch": {' 66 @echo -en '\t\t"coroutine":' 67 @+make ctxswitch-cfa_coroutine.runquiet 68 @echo -en '\t\t,"thread":' 69 @+make ctxswitch-cfa_thread.runquiet 70 @echo -e '\t},' 71 @echo -e '\t"mutex": [' 72 @echo -en '\t\t' 73 @+make mutex-cfa1.runquiet 74 @echo -en '\t\t,' 75 @+make mutex-cfa2.runquiet 76 @echo -e '\t],' 77 @echo -e '\t"scheduling": [' 78 @echo -en '\t\t' 79 @+make signal-cfa1.runquiet 80 @echo -en '\t\t,' 81 @+make signal-cfa2.runquiet 82 @echo -en '\t\t,' 83 @+make waitfor-cfa1.runquiet 84 @echo -en '\t\t,' 85 @+make waitfor-cfa2.runquiet 86 @echo -e '\n\t],' 87 @echo -e '\t"epoch": ' $(shell date +%s) 88 @echo "}" 89 90 ## ========================================================================================================= 91 ctxswitch$(EXEEXT): \ 92 ctxswitch-pthread.run \ 93 ctxswitch-cfa_coroutine.run \ 94 ctxswitch-cfa_thread.run \ 95 ctxswitch-upp_coroutine.run \ 96 ctxswitch-upp_thread.run 97 98 ctxswitch-cfa_coroutine$(EXEEXT): 99 @${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 100 101 ctxswitch-cfa_thread$(EXEEXT): 102 @${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 103 104 ctxswitch-upp_coroutine$(EXEEXT): 105 @u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 106 107 ctxswitch-upp_thread$(EXEEXT): 108 @u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 109 110 ctxswitch-pthread$(EXEEXT): 111 @@BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 112 113 ## ========================================================================================================= 114 mutex$(EXEEXT) :\ 115 mutex-function.run \ 116 mutex-pthread_lock.run \ 117 mutex-upp.run \ 118 mutex-cfa1.run \ 119 mutex-cfa2.run \ 120 mutex-cfa4.run 121 122 mutex-function$(EXEEXT): 123 @@BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 124 125 mutex-pthread_lock$(EXEEXT): 126 @@BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 127 128 mutex-upp$(EXEEXT): 129 @u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 130 131 mutex-cfa1$(EXEEXT): 132 @${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 133 134 mutex-cfa2$(EXEEXT): 135 @${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 136 137 mutex-cfa4$(EXEEXT): 138 @${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 139 140 ## ========================================================================================================= 141 signal$(EXEEXT) :\ 142 signal-upp.run \ 143 signal-cfa1.run \ 144 signal-cfa2.run \ 145 signal-cfa4.run 146 147 signal-upp$(EXEEXT): 148 @u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 149 150 signal-cfa1$(EXEEXT): 151 @${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 152 153 signal-cfa2$(EXEEXT): 154 @${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 155 156 signal-cfa4$(EXEEXT): 157 @${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 158 159 ## ========================================================================================================= 160 waitfor$(EXEEXT) :\ 161 waitfor-upp.run \ 162 waitfor-cfa1.run \ 163 waitfor-cfa2.run \ 164 waitfor-cfa4.run 165 166 waitfor-upp$(EXEEXT): 167 @u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 168 169 waitfor-cfa1$(EXEEXT): 170 @${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 171 172 waitfor-cfa2$(EXEEXT): 173 @${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 174 175 waitfor-cfa4$(EXEEXT): 176 @${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 177 178 ## ========================================================================================================= 179 creation$(EXEEXT) :\ 180 creation-pthread.run \ 181 creation-cfa_coroutine.run \ 182 creation-cfa_coroutine_eager.run \ 183 creation-cfa_thread.run \ 184 creation-upp_coroutine.run \ 185 creation-upp_thread.run 186 187 creation-cfa_coroutine$(EXEEXT): 188 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 189 190 creation-cfa_coroutine_eager$(EXEEXT): 191 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -DEAGER 192 193 creation-cfa_thread$(EXEEXT): 194 @${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 195 196 creation-upp_coroutine$(EXEEXT): 197 @u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 198 199 creation-upp_thread$(EXEEXT): 200 @u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 201 202 creation-pthread$(EXEEXT): 203 @@BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 204 205 ## ========================================================================================================= 206 207 compile$(EXEEXT) :\ 208 compile-array.make \ 209 compile-attributes.make \ 210 compile-empty.make \ 211 compile-expression.make \ 212 compile-io.make \ 213 compile-monitor.make \ 214 compile-operators.make \ 215 compile-typeof.make 216 217 218 compile-array$(EXEEXT): 219 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c 220 221 compile-attributes$(EXEEXT): 222 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c 223 224 compile-empty$(EXEEXT): 225 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c 226 227 compile-expression$(EXEEXT): 228 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c 229 230 compile-io$(EXEEXT): 231 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c 232 233 compile-monitor$(EXEEXT): 234 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c 235 236 compile-operators$(EXEEXT): 237 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c 238 239 compile-thread$(EXEEXT): 240 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c 241 242 compile-typeof$(EXEEXT): 243 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c 244 -
src/benchmark/Makefile.in
rf5c3b6c r0fe4e62 124 124 esac 125 125 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 126 am__DIST_COMMON = $(srcdir)/Makefile.in 126 am__DIST_COMMON = $(srcdir)/Makefile.in compile 127 127 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 128 128 ACLOCAL = @ACLOCAL@ … … 253 253 STATS = ${TOOLSDIR}stat.py 254 254 repeats = 30 255 TIME_FORMAT = "%E" 256 PRINT_FORMAT = '%20s\t' 255 257 all: all-am 256 258 … … 444 446 .NOTPARALLEL: 445 447 446 bench$(EXEEXT) : 447 @for ccflags in "-debug" "-nodebug"; do \ 448 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\ 449 ${CC} ${AM_CFLAGS} ${CFLAGS} $${ccflags} -lrt bench.c;\ 450 ./a.out ; \ 451 done ; \ 452 rm -f ./a.out ; 453 454 csv-data$(EXEEXT): 455 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=50000000 csv-data.c 456 @./a.out 457 @rm -f ./a.out 458 459 ctxswitch$(EXEEXT): \ 460 ctxswitch-pthread.run \ 461 ctxswitch-cfa_coroutine.run \ 462 ctxswitch-cfa_thread.run \ 463 ctxswitch-upp_coroutine.run \ 464 ctxswitch-upp_thread.run 465 466 ctxswitch-cfa_coroutine$(EXEEXT): 467 ${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 468 469 ctxswitch-cfa_thread$(EXEEXT): 470 ${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 471 472 ctxswitch-upp_coroutine$(EXEEXT): 473 u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 474 475 ctxswitch-upp_thread$(EXEEXT): 476 u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 477 478 ctxswitch-pthread$(EXEEXT): 479 @BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 480 481 creation$(EXEEXT) :\ 482 creation-pthread.run \ 483 creation-cfa_coroutine.run \ 484 creation-cfa_thread.run \ 485 creation-upp_coroutine.run \ 486 creation-upp_thread.run 487 488 creation-cfa_coroutine$(EXEEXT): 489 ${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 490 491 creation-cfa_thread$(EXEEXT): 492 ${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 493 494 creation-upp_coroutine$(EXEEXT): 495 u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 496 497 creation-upp_thread$(EXEEXT): 498 u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 499 500 creation-pthread$(EXEEXT): 501 @BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 502 503 mutex$(EXEEXT) :\ 504 mutex-function.run \ 505 mutex-pthread_lock.run \ 506 mutex-upp.run \ 507 mutex-cfa1.run \ 508 mutex-cfa2.run \ 509 mutex-cfa4.run 510 511 mutex-function$(EXEEXT): 512 @BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 513 514 mutex-pthread_lock$(EXEEXT): 515 @BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 516 517 mutex-upp$(EXEEXT): 518 u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 519 520 mutex-cfa1$(EXEEXT): 521 ${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 522 523 mutex-cfa2$(EXEEXT): 524 ${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 525 526 mutex-cfa4$(EXEEXT): 527 ${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 528 529 signal$(EXEEXT) :\ 530 signal-upp.run \ 531 signal-cfa1.run \ 532 signal-cfa2.run \ 533 signal-cfa4.run 534 535 signal-upp$(EXEEXT): 536 u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 537 538 signal-cfa1$(EXEEXT): 539 ${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 540 541 signal-cfa2$(EXEEXT): 542 ${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 543 544 signal-cfa4$(EXEEXT): 545 ${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 546 547 waitfor$(EXEEXT) :\ 548 waitfor-upp.run \ 549 waitfor-cfa1.run \ 550 waitfor-cfa2.run \ 551 waitfor-cfa4.run 552 553 waitfor-upp$(EXEEXT): 554 u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 555 556 waitfor-cfa1$(EXEEXT): 557 ${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 558 559 waitfor-cfa2$(EXEEXT): 560 ${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 561 562 waitfor-cfa4$(EXEEXT): 563 ${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 448 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT) 564 449 565 450 %.run : %$(EXEEXT) ${REPEAT} … … 572 457 @rm -f a.out .result.log 573 458 459 %.runquiet : 460 @+make $(basename $@) 461 @./a.out 462 @rm -f a.out 463 464 %.make : 465 @printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@)) 466 @+/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1 467 574 468 ${REPEAT} : 575 469 @+make -C ${TOOLSDIR} repeat 470 471 jenkins$(EXEEXT): 472 @echo "{" 473 @echo -e '\t"githash": "'${githash}'",' 474 @echo -e '\t"arch": "' ${arch} '",' 475 @echo -e '\t"compile": {' 476 @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :' 477 @echo -e '\t\t"dummy" : {}' 478 @echo -e '\t},' 479 @echo -e '\t"ctxswitch": {' 480 @echo -en '\t\t"coroutine":' 481 @+make ctxswitch-cfa_coroutine.runquiet 482 @echo -en '\t\t,"thread":' 483 @+make ctxswitch-cfa_thread.runquiet 484 @echo -e '\t},' 485 @echo -e '\t"mutex": [' 486 @echo -en '\t\t' 487 @+make mutex-cfa1.runquiet 488 @echo -en '\t\t,' 489 @+make mutex-cfa2.runquiet 490 @echo -e '\t],' 491 @echo -e '\t"scheduling": [' 492 @echo -en '\t\t' 493 @+make signal-cfa1.runquiet 494 @echo -en '\t\t,' 495 @+make signal-cfa2.runquiet 496 @echo -en '\t\t,' 497 @+make waitfor-cfa1.runquiet 498 @echo -en '\t\t,' 499 @+make waitfor-cfa2.runquiet 500 @echo -e '\n\t],' 501 @echo -e '\t"epoch": ' $(shell date +%s) 502 @echo "}" 503 504 ctxswitch$(EXEEXT): \ 505 ctxswitch-pthread.run \ 506 ctxswitch-cfa_coroutine.run \ 507 ctxswitch-cfa_thread.run \ 508 ctxswitch-upp_coroutine.run \ 509 ctxswitch-upp_thread.run 510 511 ctxswitch-cfa_coroutine$(EXEEXT): 512 @${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 513 514 ctxswitch-cfa_thread$(EXEEXT): 515 @${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 516 517 ctxswitch-upp_coroutine$(EXEEXT): 518 @u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 519 520 ctxswitch-upp_thread$(EXEEXT): 521 @u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 522 523 ctxswitch-pthread$(EXEEXT): 524 @@BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 525 526 mutex$(EXEEXT) :\ 527 mutex-function.run \ 528 mutex-pthread_lock.run \ 529 mutex-upp.run \ 530 mutex-cfa1.run \ 531 mutex-cfa2.run \ 532 mutex-cfa4.run 533 534 mutex-function$(EXEEXT): 535 @@BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 536 537 mutex-pthread_lock$(EXEEXT): 538 @@BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 539 540 mutex-upp$(EXEEXT): 541 @u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 542 543 mutex-cfa1$(EXEEXT): 544 @${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 545 546 mutex-cfa2$(EXEEXT): 547 @${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 548 549 mutex-cfa4$(EXEEXT): 550 @${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 551 552 signal$(EXEEXT) :\ 553 signal-upp.run \ 554 signal-cfa1.run \ 555 signal-cfa2.run \ 556 signal-cfa4.run 557 558 signal-upp$(EXEEXT): 559 @u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 560 561 signal-cfa1$(EXEEXT): 562 @${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 563 564 signal-cfa2$(EXEEXT): 565 @${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 566 567 signal-cfa4$(EXEEXT): 568 @${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 569 570 waitfor$(EXEEXT) :\ 571 waitfor-upp.run \ 572 waitfor-cfa1.run \ 573 waitfor-cfa2.run \ 574 waitfor-cfa4.run 575 576 waitfor-upp$(EXEEXT): 577 @u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 578 579 waitfor-cfa1$(EXEEXT): 580 @${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 581 582 waitfor-cfa2$(EXEEXT): 583 @${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 584 585 waitfor-cfa4$(EXEEXT): 586 @${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 587 588 creation$(EXEEXT) :\ 589 creation-pthread.run \ 590 creation-cfa_coroutine.run \ 591 creation-cfa_coroutine_eager.run \ 592 creation-cfa_thread.run \ 593 creation-upp_coroutine.run \ 594 creation-upp_thread.run 595 596 creation-cfa_coroutine$(EXEEXT): 597 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 598 599 creation-cfa_coroutine_eager$(EXEEXT): 600 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -DEAGER 601 602 creation-cfa_thread$(EXEEXT): 603 @${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 604 605 creation-upp_coroutine$(EXEEXT): 606 @u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 607 608 creation-upp_thread$(EXEEXT): 609 @u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 610 611 creation-pthread$(EXEEXT): 612 @@BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 613 614 compile$(EXEEXT) :\ 615 compile-array.make \ 616 compile-attributes.make \ 617 compile-empty.make \ 618 compile-expression.make \ 619 compile-io.make \ 620 compile-monitor.make \ 621 compile-operators.make \ 622 compile-typeof.make 623 624 compile-array$(EXEEXT): 625 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c 626 627 compile-attributes$(EXEEXT): 628 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c 629 630 compile-empty$(EXEEXT): 631 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c 632 633 compile-expression$(EXEEXT): 634 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c 635 636 compile-io$(EXEEXT): 637 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c 638 639 compile-monitor$(EXEEXT): 640 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c 641 642 compile-operators$(EXEEXT): 643 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c 644 645 compile-thread$(EXEEXT): 646 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c 647 648 compile-typeof$(EXEEXT): 649 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c 576 650 577 651 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
src/benchmark/creation/cfa_cor.c
rf5c3b6c r0fe4e62 5 5 6 6 coroutine MyCoroutine {}; 7 void ?{} (MyCoroutine & this) { prime(this); } 7 void ?{} (MyCoroutine & this) { 8 #ifdef EAGER 9 prime(this); 10 #endif 11 } 8 12 void main(MyCoroutine & this) {} 9 13 -
src/benchmark/csv-data.c
rf5c3b6c r0fe4e62 28 28 // coroutine context switch 29 29 long long int measure_coroutine() { 30 const unsigned int NoOfTimes = N;30 const unsigned int NoOfTimes = 50000000; 31 31 long long int StartTime, EndTime; 32 32 … … 43 43 // thread context switch 44 44 long long int measure_thread() { 45 const unsigned int NoOfTimes = N;45 const unsigned int NoOfTimes = 50000000; 46 46 long long int StartTime, EndTime; 47 47 … … 61 61 62 62 long long int measure_1_monitor_entry() { 63 const unsigned int NoOfTimes = N;63 const unsigned int NoOfTimes = 5000000; 64 64 long long int StartTime, EndTime; 65 65 mon_t mon; … … 79 79 80 80 long long int measure_2_monitor_entry() { 81 const unsigned int NoOfTimes = N;81 const unsigned int NoOfTimes = 5000000; 82 82 long long int StartTime, EndTime; 83 83 mon_t mon1, mon2; … … 94 94 //----------------------------------------------------------------------------- 95 95 // single internal sched entry 96 const unsigned int NoOfTimes = 500000; 97 96 98 mon_t mon1; 97 99 … … 107 109 108 110 void side1A( mon_t & mutex a, long long int * out ) { 109 long long int StartTime, EndTime; 110 111 StartTime = Time(); 112 for( int i = 0;; i++ ) { 113 signal(&cond1a); 111 const unsigned int NoOfTimes = 500000; 112 long long int StartTime, EndTime; 113 114 StartTime = Time(); 115 for( int i = 0;; i++ ) { 116 signal(cond1a); 117 if( i > NoOfTimes ) break; 118 wait(cond1b); 119 } 120 EndTime = Time(); 121 122 *out = ( EndTime - StartTime ) / NoOfTimes; 123 } 124 125 void side1B( mon_t & mutex a ) { 126 for( int i = 0;; i++ ) { 127 signal(cond1b); 114 128 if( i > N ) break; 115 wait(&cond1b); 116 } 117 EndTime = Time(); 118 119 *out = ( EndTime - StartTime ) / N; 120 } 121 122 void side1B( mon_t & mutex a ) { 123 for( int i = 0;; i++ ) { 124 signal(&cond1b); 125 if( i > N ) break; 126 wait(&cond1a); 129 wait(cond1a); 127 130 } 128 131 } … … 141 144 142 145 //----------------------------------------------------------------------------- 143 // multi internal sched entry146 // multi internal sched 144 147 mon_t mon2; 145 148 … … 155 158 156 159 void side2A( mon_t & mutex a, mon_t & mutex b, long long int * out ) { 157 long long int StartTime, EndTime; 158 159 StartTime = Time(); 160 for( int i = 0;; i++ ) { 161 signal(&cond2a); 160 const unsigned int NoOfTimes = 500000; 161 long long int StartTime, EndTime; 162 163 StartTime = Time(); 164 for( int i = 0;; i++ ) { 165 signal(cond2a); 166 if( i > NoOfTimes ) break; 167 wait(cond2b); 168 } 169 EndTime = Time(); 170 171 *out = ( EndTime - StartTime ) / NoOfTimes; 172 } 173 174 void side2B( mon_t & mutex a, mon_t & mutex b ) { 175 for( int i = 0;; i++ ) { 176 signal(cond2b); 162 177 if( i > N ) break; 163 wait(&cond2b); 164 } 165 EndTime = Time(); 166 167 *out = ( EndTime - StartTime ) / N; 168 } 169 170 void side2B( mon_t & mutex a, mon_t & mutex b ) { 171 for( int i = 0;; i++ ) { 172 signal(&cond2b); 173 if( i > N ) break; 174 wait(&cond2a); 178 wait(cond2a); 175 179 } 176 180 } … … 189 193 190 194 //----------------------------------------------------------------------------- 195 // single external sched 196 197 volatile int go = 0; 198 199 void __attribute__((noinline)) call( mon_t & mutex m1 ) {} 200 201 long long int __attribute__((noinline)) wait( mon_t & mutex m1 ) { 202 go = 1; 203 const unsigned int NoOfTimes = 5000000; 204 long long int StartTime, EndTime; 205 206 StartTime = Time(); 207 for (size_t i = 0; i < NoOfTimes; i++) { 208 waitfor(call, m1); 209 } 210 211 EndTime = Time(); 212 go = 0; 213 return ( EndTime - StartTime ) / NoOfTimes; 214 } 215 216 thread thrd3 {}; 217 void ^?{}( thrd3 & mutex this ) {} 218 void main( thrd3 & this ) { 219 while(go == 0) { yield(); } 220 while(go == 1) { call(mon1); } 221 222 } 223 224 long long int measure_1_sched_ext() { 225 go = 0; 226 thrd3 t; 227 return wait(mon1); 228 } 229 230 //----------------------------------------------------------------------------- 231 // multi external sched 232 233 void __attribute__((noinline)) call( mon_t & mutex m1, mon_t & mutex m2 ) {} 234 235 long long int __attribute__((noinline)) wait( mon_t & mutex m1, mon_t & mutex m2 ) { 236 go = 1; 237 const unsigned int NoOfTimes = 5000000; 238 long long int StartTime, EndTime; 239 240 StartTime = Time(); 241 for (size_t i = 0; i < NoOfTimes; i++) { 242 waitfor(call, m1, m2); 243 } 244 245 EndTime = Time(); 246 go = 0; 247 return ( EndTime - StartTime ) / NoOfTimes; 248 } 249 250 thread thrd4 {}; 251 void ^?{}( thrd4 & mutex this ) {} 252 void main( thrd4 & this ) { 253 while(go == 0) { yield(); } 254 while(go == 1) { call(mon1, mon2); } 255 256 } 257 258 long long int measure_2_sched_ext() { 259 go = 0; 260 thrd3 t; 261 return wait(mon1, mon2); 262 } 263 264 //----------------------------------------------------------------------------- 191 265 // main loop 192 266 int main() 193 267 { 194 sout | time(NULL) | ','; 195 sout | measure_coroutine() | ','; 196 sout | measure_thread() | ','; 197 sout | measure_1_monitor_entry() | ','; 198 sout | measure_2_monitor_entry() | ','; 199 sout | measure_1_sched_int() | ','; 200 sout | measure_2_sched_int() | endl; 201 } 268 sout | "\tepoch:" | time(NULL) | ',' | endl; 269 sout | "\tctxswitch: {" | endl; 270 sout | "\t\tcoroutine: "| measure_coroutine() | ',' | endl; 271 sout | "\t\tthread:" | measure_thread() | ',' | endl; 272 sout | "\t}," | endl; 273 sout | "\tmutex: [" | measure_1_monitor_entry() | ',' | measure_2_monitor_entry() | "]," | endl; 274 sout | "\tscheduling: ["| measure_1_sched_int() | ',' | measure_2_sched_int() | ',' | 275 measure_1_sched_ext() | ',' | measure_2_sched_ext() | "]," | endl; 276 } -
src/benchmark/schedint/cfa1.c
rf5c3b6c r0fe4e62 15 15 16 16 void __attribute__((noinline)) call( M & mutex a1 ) { 17 signal( &c);17 signal(c); 18 18 } 19 19 … … 22 22 BENCH( 23 23 for (size_t i = 0; i < n; i++) { 24 wait( &c);24 wait(c); 25 25 }, 26 26 result -
src/benchmark/schedint/cfa2.c
rf5c3b6c r0fe4e62 15 15 16 16 void __attribute__((noinline)) call( M & mutex a1, M & mutex a2 ) { 17 signal( &c);17 signal(c); 18 18 } 19 19 … … 22 22 BENCH( 23 23 for (size_t i = 0; i < n; i++) { 24 wait( &c);24 wait(c); 25 25 }, 26 26 result -
src/benchmark/schedint/cfa4.c
rf5c3b6c r0fe4e62 15 15 16 16 void __attribute__((noinline)) call( M & mutex a1, M & mutex a2, M & mutex a3, M & mutex a4 ) { 17 signal( &c);17 signal(c); 18 18 } 19 19 … … 22 22 BENCH( 23 23 for (size_t i = 0; i < n; i++) { 24 wait( &c);24 wait(c); 25 25 }, 26 26 result -
src/libcfa/Makefile.am
rf5c3b6c r0fe4e62 95 95 96 96 cfa_includedir = $(CFA_INCDIR) 97 nobase_cfa_include_HEADERS = ${headers} ${stdhdr} math gmp concurrency/invoke.h 97 nobase_cfa_include_HEADERS = \ 98 ${headers} \ 99 ${stdhdr} \ 100 math \ 101 gmp \ 102 bits/defs.h \ 103 bits/locks.h \ 104 concurrency/invoke.h \ 105 libhdr.h \ 106 libhdr/libalign.h \ 107 libhdr/libdebug.h \ 108 libhdr/libtools.h 98 109 99 110 CLEANFILES = libcfa-prelude.c -
src/libcfa/Makefile.in
rf5c3b6c r0fe4e62 264 264 containers/result containers/vector concurrency/coroutine \ 265 265 concurrency/thread concurrency/kernel concurrency/monitor \ 266 ${shell echo stdhdr/*} math gmp concurrency/invoke.h 266 ${shell echo stdhdr/*} math gmp bits/defs.h bits/locks.h \ 267 concurrency/invoke.h libhdr.h libhdr/libalign.h \ 268 libhdr/libdebug.h libhdr/libtools.h 267 269 HEADERS = $(nobase_cfa_include_HEADERS) 268 270 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 430 432 stdhdr = ${shell echo stdhdr/*} 431 433 cfa_includedir = $(CFA_INCDIR) 432 nobase_cfa_include_HEADERS = ${headers} ${stdhdr} math gmp concurrency/invoke.h 434 nobase_cfa_include_HEADERS = \ 435 ${headers} \ 436 ${stdhdr} \ 437 math \ 438 gmp \ 439 bits/defs.h \ 440 bits/locks.h \ 441 concurrency/invoke.h \ 442 libhdr.h \ 443 libhdr/libalign.h \ 444 libhdr/libdebug.h \ 445 libhdr/libtools.h 446 433 447 CLEANFILES = libcfa-prelude.c 434 448 all: all-am -
src/libcfa/concurrency/alarm.c
rf5c3b6c r0fe4e62 186 186 187 187 disable_interrupts(); 188 lock( &event_kernel->lock DEBUG_CTX2 );188 lock( event_kernel->lock DEBUG_CTX2 ); 189 189 { 190 190 verify( validate( alarms ) ); … … 196 196 } 197 197 } 198 unlock( &event_kernel->lock );198 unlock( event_kernel->lock ); 199 199 this->set = true; 200 200 enable_interrupts( DEBUG_CTX ); … … 203 203 void unregister_self( alarm_node_t * this ) { 204 204 disable_interrupts(); 205 lock( &event_kernel->lock DEBUG_CTX2 );205 lock( event_kernel->lock DEBUG_CTX2 ); 206 206 { 207 207 verify( validate( &event_kernel->alarms ) ); 208 208 remove( &event_kernel->alarms, this ); 209 209 } 210 unlock( &event_kernel->lock );210 unlock( event_kernel->lock ); 211 211 enable_interrupts( DEBUG_CTX ); 212 212 this->set = false; -
src/libcfa/concurrency/coroutine.c
rf5c3b6c r0fe4e62 156 156 this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ); // minimum alignment 157 157 } // if 158 assertf( this->size >= MinStackSize, "Stack size % d provides less than minimum of %d bytes for a stack.", this->size, MinStackSize );158 assertf( this->size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", this->size, MinStackSize ); 159 159 160 160 this->base = (char *)this->limit + this->size; -
src/libcfa/concurrency/invoke.h
rf5c3b6c r0fe4e62 14 14 // 15 15 16 #include <stdbool.h>17 #include <stdint.h>16 #include "bits/defs.h" 17 #include "bits/locks.h" 18 18 19 19 #ifdef __CFORALL__ … … 25 25 #define _INVOKE_H_ 26 26 27 #define unlikely(x) __builtin_expect(!!(x), 0) 28 #define thread_local _Thread_local 29 30 typedef void (*fptr_t)(); 31 32 struct spinlock { 33 volatile int lock; 34 #ifdef __CFA_DEBUG__ 35 const char * prev_name; 36 void* prev_thrd; 37 #endif 38 }; 39 40 struct __thread_queue_t { 41 struct thread_desc * head; 42 struct thread_desc ** tail; 43 }; 44 45 struct __condition_stack_t { 46 struct __condition_criterion_t * top; 47 }; 48 49 #ifdef __CFORALL__ 50 extern "Cforall" { 51 void ?{}( struct __thread_queue_t & ); 52 void append( struct __thread_queue_t *, struct thread_desc * ); 53 struct thread_desc * pop_head( struct __thread_queue_t * ); 54 struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** ); 55 56 void ?{}( struct __condition_stack_t & ); 57 void push( struct __condition_stack_t *, struct __condition_criterion_t * ); 58 struct __condition_criterion_t * pop( struct __condition_stack_t * ); 59 60 void ?{}(spinlock & this); 61 void ^?{}(spinlock & this); 62 } 63 #endif 64 65 struct coStack_t { 66 unsigned int size; // size of stack 67 void *storage; // pointer to stack 68 void *limit; // stack grows towards stack limit 69 void *base; // base of stack 70 void *context; // address of cfa_context_t 71 void *top; // address of top of storage 72 bool userStack; // whether or not the user allocated the stack 73 }; 74 75 enum coroutine_state { Halted, Start, Inactive, Active, Primed }; 76 77 struct coroutine_desc { 78 struct coStack_t stack; // stack information of the coroutine 79 const char *name; // textual name for coroutine/task, initialized by uC++ generated code 80 int errno_; // copy of global UNIX variable errno 81 enum coroutine_state state; // current execution status for coroutine 82 struct coroutine_desc * starter; // first coroutine to resume this one 83 struct coroutine_desc * last; // last coroutine to resume this one 84 }; 85 86 struct __waitfor_mask_t { 87 short * accepted; // the index of the accepted function, -1 if none 88 struct __acceptable_t * clauses; // list of acceptable functions, null if any 89 short size; // number of acceptable functions 90 }; 91 92 struct monitor_desc { 93 struct spinlock lock; // spinlock to protect internal data 94 struct thread_desc * owner; // current owner of the monitor 95 struct __thread_queue_t entry_queue; // queue of threads that are blocked waiting for the monitor 96 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 97 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor 99 struct __condition_node_t * dtor_node; // node used to signal the dtor in a waitfor dtor 100 }; 101 102 struct __monitor_group_t { 103 struct monitor_desc ** list; // currently held monitors 104 short size; // number of currently held monitors 105 fptr_t func; // last function that acquired monitors 106 }; 107 108 struct thread_desc { 109 // Core threading fields 110 struct coroutine_desc self_cor; // coroutine body used to store context 111 struct monitor_desc self_mon; // monitor body used for mutual exclusion 112 struct monitor_desc * self_mon_p; // pointer to monitor with sufficient lifetime for current monitors 113 struct __monitor_group_t monitors; // monitors currently held by this thread 114 115 // Link lists fields 116 struct thread_desc * next; // instrusive link field for threads 117 118 27 typedef void (*fptr_t)(); 28 typedef int_fast16_t __lock_size_t; 29 30 struct __thread_queue_t { 31 struct thread_desc * head; 32 struct thread_desc ** tail; 33 }; 34 35 struct __condition_stack_t { 36 struct __condition_criterion_t * top; 37 }; 38 39 #ifdef __CFORALL__ 40 extern "Cforall" { 41 void ?{}( struct __thread_queue_t & ); 42 void append( struct __thread_queue_t &, struct thread_desc * ); 43 struct thread_desc * pop_head( struct __thread_queue_t & ); 44 struct thread_desc * remove( struct __thread_queue_t &, struct thread_desc ** ); 45 46 void ?{}( struct __condition_stack_t & ); 47 void push( struct __condition_stack_t &, struct __condition_criterion_t * ); 48 struct __condition_criterion_t * pop( struct __condition_stack_t & ); 49 } 50 #endif 51 52 struct coStack_t { 53 // size of stack 54 size_t size; 55 56 // pointer to stack 57 void *storage; 58 59 // stack grows towards stack limit 60 void *limit; 61 62 // base of stack 63 void *base; 64 65 // address of cfa_context_t 66 void *context; 67 68 // address of top of storage 69 void *top; 70 71 // whether or not the user allocated the stack 72 bool userStack; 73 }; 74 75 enum coroutine_state { Halted, Start, Inactive, Active, Primed }; 76 77 struct coroutine_desc { 78 // stack information of the coroutine 79 struct coStack_t stack; 80 81 // textual name for coroutine/task, initialized by uC++ generated code 82 const char *name; 83 84 // copy of global UNIX variable errno 85 int errno_; 86 87 // current execution status for coroutine 88 enum coroutine_state state; 89 90 // first coroutine to resume this one 91 struct coroutine_desc * starter; 92 93 // last coroutine to resume this one 94 struct coroutine_desc * last; 95 }; 96 97 struct __waitfor_mask_t { 98 // the index of the accepted function, -1 if none 99 short * accepted; 100 101 // list of acceptable functions, null if any 102 struct __acceptable_t * clauses; 103 104 // number of acceptable functions 105 __lock_size_t size; 106 }; 107 108 struct monitor_desc { 109 // spinlock to protect internal data 110 struct __spinlock_t lock; 111 112 // current owner of the monitor 113 struct thread_desc * owner; 114 115 // queue of threads that are blocked waiting for the monitor 116 struct __thread_queue_t entry_queue; 117 118 // stack of conditions to run next once we exit the monitor 119 struct __condition_stack_t signal_stack; 120 121 // monitor routines can be called recursively, we need to keep track of that 122 unsigned int recursion; 123 124 // mask used to know if some thread is waiting for something while holding the monitor 125 struct __waitfor_mask_t mask; 126 127 // node used to signal the dtor in a waitfor dtor 128 struct __condition_node_t * dtor_node; 129 }; 130 131 struct __monitor_group_t { 132 // currently held monitors 133 struct monitor_desc ** list; 134 135 // number of currently held monitors 136 __lock_size_t size; 137 138 // last function that acquired monitors 139 fptr_t func; 140 }; 141 142 struct thread_desc { 143 // Core threading fields 144 // coroutine body used to store context 145 struct coroutine_desc self_cor; 146 147 // monitor body used for mutual exclusion 148 struct monitor_desc self_mon; 149 150 // pointer to monitor with sufficient lifetime for current monitors 151 struct monitor_desc * self_mon_p; 152 153 // monitors currently held by this thread 154 struct __monitor_group_t monitors; 155 156 // Link lists fields 157 // instrusive link field for threads 158 struct thread_desc * next; 119 159 }; 120 160 121 161 #ifdef __CFORALL__ 122 162 extern "Cforall" { 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 163 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) { 164 return this.list[index]; 165 } 166 167 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) { 168 if( (lhs.list != 0) != (rhs.list != 0) ) return false; 169 if( lhs.size != rhs.size ) return false; 170 if( lhs.func != rhs.func ) return false; 171 172 // Check that all the monitors match 173 for( int i = 0; i < lhs.size; i++ ) { 174 // If not a match, check next function 175 if( lhs[i] != rhs[i] ) return false; 176 } 177 178 return true; 179 } 180 } 181 #endif 142 182 143 183 #endif //_INVOKE_H_ … … 146 186 #define _INVOKE_PRIVATE_H_ 147 187 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 188 struct machine_context_t { 189 void *SP; 190 void *FP; 191 void *PC; 192 }; 193 194 // assembler routines that performs the context switch 195 extern void CtxInvokeStub( void ); 196 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch"); 197 198 #if defined( __x86_64__ ) 199 #define CtxGet( ctx ) __asm__ ( \ 200 "movq %%rsp,%0\n" \ 201 "movq %%rbp,%1\n" \ 202 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 203 #elif defined( __i386__ ) 204 #define CtxGet( ctx ) __asm__ ( \ 205 "movl %%esp,%0\n" \ 206 "movl %%ebp,%1\n" \ 207 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 208 #endif 169 209 170 210 #endif //_INVOKE_PRIVATE_H_ -
src/libcfa/concurrency/kernel
rf5c3b6c r0fe4e62 26 26 //----------------------------------------------------------------------------- 27 27 // Locks 28 void lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, spin if already acquired 29 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, yield repeatedly if already acquired 30 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, return false if already acquired 31 void unlock ( spinlock * ); // Unlock the spinlock 28 // // Lock the spinlock, spin if already acquired 29 // void lock ( spinlock * DEBUG_CTX_PARAM2 ); 30 31 // // Lock the spinlock, yield repeatedly if already acquired 32 // void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 34 // // Lock the spinlock, return false if already acquired 35 // bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 36 37 // // Unlock the spinlock 38 // void unlock ( spinlock * ); 32 39 33 40 struct semaphore { 34 spinlocklock;41 __spinlock_t lock; 35 42 int count; 36 43 __thread_queue_t waiting; … … 39 46 void ?{}(semaphore & this, int count = 1); 40 47 void ^?{}(semaphore & this); 41 void P(semaphore *this);42 void V(semaphore *this);48 void P (semaphore & this); 49 void V (semaphore & this); 43 50 44 51 … … 46 53 // Cluster 47 54 struct cluster { 48 spinlock ready_queue_lock; // Ready queue locks 49 __thread_queue_t ready_queue; // Ready queue for threads 50 unsigned long long int preemption; // Preemption rate on this cluster 55 // Ready queue locks 56 __spinlock_t ready_queue_lock; 57 58 // Ready queue for threads 59 __thread_queue_t ready_queue; 60 61 // Preemption rate on this cluster 62 unsigned long long int preemption; 51 63 }; 52 64 53 void ?{} (cluster & this);65 void ?{} (cluster & this); 54 66 void ^?{}(cluster & this); 55 67 … … 62 74 FinishOpCode action_code; 63 75 thread_desc * thrd; 64 spinlock* lock;65 spinlock** locks;76 __spinlock_t * lock; 77 __spinlock_t ** locks; 66 78 unsigned short lock_count; 67 79 thread_desc ** thrds; … … 79 91 struct processor { 80 92 // Main state 81 struct processorCtx_t * runner; // Coroutine ctx who does keeps the state of the processor 82 cluster * cltr; // Cluster from which to get threads 83 pthread_t kernel_thread; // Handle to pthreads 93 // Coroutine ctx who does keeps the state of the processor 94 struct processorCtx_t * runner; 95 96 // Cluster from which to get threads 97 cluster * cltr; 98 99 // Handle to pthreads 100 pthread_t kernel_thread; 84 101 85 102 // Termination 86 volatile bool do_terminate; // Set to true to notify the processor should terminate 87 semaphore terminated; // Termination synchronisation 103 // Set to true to notify the processor should terminate 104 volatile bool do_terminate; 105 106 // Termination synchronisation 107 semaphore terminated; 88 108 89 109 // RunThread data 90 struct FinishAction finish; // Action to do after a thread is ran 110 // Action to do after a thread is ran 111 struct FinishAction finish; 91 112 92 113 // Preemption data 93 struct alarm_node_t * preemption_alarm; // Node which is added in the discrete event simulaiton 94 bool pending_preemption; // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible 114 // Node which is added in the discrete event simulaiton 115 struct alarm_node_t * preemption_alarm; 116 117 // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible 118 bool pending_preemption; 95 119 96 120 #ifdef __CFA_DEBUG__ 97 char * last_enable; // Last function to enable preemption on this processor 121 // Last function to enable preemption on this processor 122 char * last_enable; 98 123 #endif 99 124 }; 100 125 101 void ?{}(processor & this);102 void ?{}(processor & this, cluster * cltr);126 void ?{}(processor & this); 127 void ?{}(processor & this, cluster * cltr); 103 128 void ^?{}(processor & this); 104 129 -
src/libcfa/concurrency/kernel.c
rf5c3b6c r0fe4e62 158 158 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", &this); 159 159 this.do_terminate = true; 160 P( &this.terminated );160 P( this.terminated ); 161 161 pthread_join( this.kernel_thread, NULL ); 162 162 } … … 216 216 } 217 217 218 V( &this->terminated );218 V( this->terminated ); 219 219 220 220 LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this); … … 242 242 void finishRunning(processor * this) { 243 243 if( this->finish.action_code == Release ) { 244 unlock( this->finish.lock );244 unlock( *this->finish.lock ); 245 245 } 246 246 else if( this->finish.action_code == Schedule ) { … … 248 248 } 249 249 else if( this->finish.action_code == Release_Schedule ) { 250 unlock( this->finish.lock );250 unlock( *this->finish.lock ); 251 251 ScheduleThread( this->finish.thrd ); 252 252 } 253 253 else if( this->finish.action_code == Release_Multi ) { 254 254 for(int i = 0; i < this->finish.lock_count; i++) { 255 unlock( this->finish.locks[i] );255 unlock( *this->finish.locks[i] ); 256 256 } 257 257 } 258 258 else if( this->finish.action_code == Release_Multi_Schedule ) { 259 259 for(int i = 0; i < this->finish.lock_count; i++) { 260 unlock( this->finish.locks[i] );260 unlock( *this->finish.locks[i] ); 261 261 } 262 262 for(int i = 0; i < this->finish.thrd_count; i++) { … … 334 334 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 335 335 336 lock( &this_processor->cltr->ready_queue_lock DEBUG_CTX2 );337 append( &this_processor->cltr->ready_queue, thrd );338 unlock( &this_processor->cltr->ready_queue_lock );336 lock( this_processor->cltr->ready_queue_lock DEBUG_CTX2 ); 337 append( this_processor->cltr->ready_queue, thrd ); 338 unlock( this_processor->cltr->ready_queue_lock ); 339 339 340 340 verify( disable_preempt_count > 0 ); … … 343 343 thread_desc * nextThread(cluster * this) { 344 344 verify( disable_preempt_count > 0 ); 345 lock( &this->ready_queue_lock DEBUG_CTX2 );346 thread_desc * head = pop_head( &this->ready_queue );347 unlock( &this->ready_queue_lock );345 lock( this->ready_queue_lock DEBUG_CTX2 ); 346 thread_desc * head = pop_head( this->ready_queue ); 347 unlock( this->ready_queue_lock ); 348 348 verify( disable_preempt_count > 0 ); 349 349 return head; … … 358 358 } 359 359 360 void BlockInternal( spinlock* lock ) {360 void BlockInternal( __spinlock_t * lock ) { 361 361 disable_interrupts(); 362 362 this_processor->finish.action_code = Release; … … 384 384 } 385 385 386 void BlockInternal( spinlock* lock, thread_desc * thrd ) {386 void BlockInternal( __spinlock_t * lock, thread_desc * thrd ) { 387 387 assert(thrd); 388 388 disable_interrupts(); … … 398 398 } 399 399 400 void BlockInternal( spinlock ** locks, unsigned short count) {400 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 401 401 disable_interrupts(); 402 402 this_processor->finish.action_code = Release_Multi; … … 411 411 } 412 412 413 void BlockInternal( spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {413 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 414 414 disable_interrupts(); 415 415 this_processor->finish.action_code = Release_Multi_Schedule; … … 426 426 } 427 427 428 void LeaveThread( spinlock* lock, thread_desc * thrd) {428 void LeaveThread(__spinlock_t * lock, thread_desc * thrd) { 429 429 verify( disable_preempt_count > 0 ); 430 430 this_processor->finish.action_code = thrd ? Release_Schedule : Release; … … 516 516 } 517 517 518 static spinlockkernel_abort_lock;519 static spinlockkernel_debug_lock;518 static __spinlock_t kernel_abort_lock; 519 static __spinlock_t kernel_debug_lock; 520 520 static bool kernel_abort_called = false; 521 521 … … 523 523 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 524 524 // the globalAbort flag is true. 525 lock( &kernel_abort_lock DEBUG_CTX2 );525 lock( kernel_abort_lock DEBUG_CTX2 ); 526 526 527 527 // first task to abort ? 528 528 if ( !kernel_abort_called ) { // not first task to abort ? 529 529 kernel_abort_called = true; 530 unlock( &kernel_abort_lock );530 unlock( kernel_abort_lock ); 531 531 } 532 532 else { 533 unlock( &kernel_abort_lock );533 unlock( kernel_abort_lock ); 534 534 535 535 sigset_t mask; … … 561 561 extern "C" { 562 562 void __lib_debug_acquire() { 563 lock( &kernel_debug_lock DEBUG_CTX2 );563 lock( kernel_debug_lock DEBUG_CTX2 ); 564 564 } 565 565 566 566 void __lib_debug_release() { 567 unlock( &kernel_debug_lock );567 unlock( kernel_debug_lock ); 568 568 } 569 569 } … … 574 574 //----------------------------------------------------------------------------- 575 575 // Locks 576 void ?{}( spinlock & this ) {577 this.lock = 0;578 }579 void ^?{}( spinlock & this ) {580 581 }582 583 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {584 return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;585 }586 587 void lock( spinlock * this DEBUG_CTX_PARAM2 ) {588 for ( unsigned int i = 1;; i += 1 ) {589 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }590 }591 LIB_DEBUG_DO(592 this->prev_name = caller;593 this->prev_thrd = this_thread;594 )595 }596 597 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) {598 for ( unsigned int i = 1;; i += 1 ) {599 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }600 yield();601 }602 LIB_DEBUG_DO(603 this->prev_name = caller;604 this->prev_thrd = this_thread;605 )606 }607 608 609 void unlock( spinlock * this ) {610 __sync_lock_release_4( &this->lock );611 }612 613 576 void ?{}( semaphore & this, int count = 1 ) { 614 577 (this.lock){}; … … 618 581 void ^?{}(semaphore & this) {} 619 582 620 void P(semaphore *this) {621 lock( &this->lock DEBUG_CTX2 );622 this ->count -= 1;623 if ( this ->count < 0 ) {583 void P(semaphore & this) { 584 lock( this.lock DEBUG_CTX2 ); 585 this.count -= 1; 586 if ( this.count < 0 ) { 624 587 // queue current task 625 append( &this->waiting, (thread_desc *)this_thread );588 append( this.waiting, (thread_desc *)this_thread ); 626 589 627 590 // atomically release spin lock and block 628 BlockInternal( &this ->lock );591 BlockInternal( &this.lock ); 629 592 } 630 593 else { 631 unlock( &this->lock );632 } 633 } 634 635 void V(semaphore *this) {594 unlock( this.lock ); 595 } 596 } 597 598 void V(semaphore & this) { 636 599 thread_desc * thrd = NULL; 637 lock( &this->lock DEBUG_CTX2 );638 this ->count += 1;639 if ( this ->count <= 0 ) {600 lock( this.lock DEBUG_CTX2 ); 601 this.count += 1; 602 if ( this.count <= 0 ) { 640 603 // remove task at head of waiting list 641 thrd = pop_head( &this->waiting );642 } 643 644 unlock( &this->lock );604 thrd = pop_head( this.waiting ); 605 } 606 607 unlock( this.lock ); 645 608 646 609 // make new owner … … 655 618 } 656 619 657 void append( __thread_queue_t *this, thread_desc * t ) {658 verify(this ->tail != NULL);659 *this ->tail = t;660 this ->tail = &t->next;661 } 662 663 thread_desc * pop_head( __thread_queue_t *this ) {664 thread_desc * head = this ->head;620 void append( __thread_queue_t & this, thread_desc * t ) { 621 verify(this.tail != NULL); 622 *this.tail = t; 623 this.tail = &t->next; 624 } 625 626 thread_desc * pop_head( __thread_queue_t & this ) { 627 thread_desc * head = this.head; 665 628 if( head ) { 666 this ->head = head->next;629 this.head = head->next; 667 630 if( !head->next ) { 668 this ->tail = &this->head;631 this.tail = &this.head; 669 632 } 670 633 head->next = NULL; … … 673 636 } 674 637 675 thread_desc * remove( __thread_queue_t *this, thread_desc ** it ) {638 thread_desc * remove( __thread_queue_t & this, thread_desc ** it ) { 676 639 thread_desc * thrd = *it; 677 640 verify( thrd ); … … 679 642 (*it) = thrd->next; 680 643 681 if( this ->tail == &thrd->next ) {682 this ->tail = it;644 if( this.tail == &thrd->next ) { 645 this.tail = it; 683 646 } 684 647 685 648 thrd->next = NULL; 686 649 687 verify( (this ->head == NULL) == (&this->head == this->tail) );688 verify( *this ->tail == NULL );650 verify( (this.head == NULL) == (&this.head == this.tail) ); 651 verify( *this.tail == NULL ); 689 652 return thrd; 690 653 } … … 694 657 } 695 658 696 void push( __condition_stack_t *this, __condition_criterion_t * t ) {659 void push( __condition_stack_t & this, __condition_criterion_t * t ) { 697 660 verify( !t->next ); 698 t->next = this ->top;699 this ->top = t;700 } 701 702 __condition_criterion_t * pop( __condition_stack_t *this ) {703 __condition_criterion_t * top = this ->top;661 t->next = this.top; 662 this.top = t; 663 } 664 665 __condition_criterion_t * pop( __condition_stack_t & this ) { 666 __condition_criterion_t * top = this.top; 704 667 if( top ) { 705 this ->top = top->next;668 this.top = top->next; 706 669 top->next = NULL; 707 670 } -
src/libcfa/concurrency/kernel_private.h
rf5c3b6c r0fe4e62 45 45 //Block current thread and release/wake-up the following resources 46 46 void BlockInternal(void); 47 void BlockInternal( spinlock* lock);47 void BlockInternal(__spinlock_t * lock); 48 48 void BlockInternal(thread_desc * thrd); 49 void BlockInternal( spinlock* lock, thread_desc * thrd);50 void BlockInternal( spinlock ** locks, unsigned short count);51 void BlockInternal( spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);52 void LeaveThread( spinlock* lock, thread_desc * thrd);49 void BlockInternal(__spinlock_t * lock, thread_desc * thrd); 50 void BlockInternal(__spinlock_t * locks [], unsigned short count); 51 void BlockInternal(__spinlock_t * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count); 52 void LeaveThread(__spinlock_t * lock, thread_desc * thrd); 53 53 54 54 //----------------------------------------------------------------------------- … … 66 66 struct event_kernel_t { 67 67 alarm_list_t alarms; 68 spinlocklock;68 __spinlock_t lock; 69 69 }; 70 70 -
src/libcfa/concurrency/monitor
rf5c3b6c r0fe4e62 39 39 } 40 40 41 // static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {42 // return ((intptr_t)lhs) < ((intptr_t)rhs);43 // }44 45 41 struct monitor_guard_t { 46 42 monitor_desc ** m; 47 intcount;43 __lock_size_t count; 48 44 monitor_desc ** prev_mntrs; 49 unsigned shortprev_count;45 __lock_size_t prev_count; 50 46 fptr_t prev_func; 51 47 }; 52 48 53 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );49 void ?{}( monitor_guard_t & this, monitor_desc ** m, __lock_size_t count, void (*func)() ); 54 50 void ^?{}( monitor_guard_t & this ); 55 51 … … 57 53 monitor_desc * m; 58 54 monitor_desc ** prev_mntrs; 59 unsigned shortprev_count;55 __lock_size_t prev_count; 60 56 fptr_t prev_func; 61 57 }; … … 74 70 75 71 struct __condition_criterion_t { 76 bool ready; //Whether or not the criterion is met (True if met) 77 monitor_desc * target; //The monitor this criterion concerns 78 struct __condition_node_t * owner; //The parent node to which this criterion belongs 79 __condition_criterion_t * next; //Intrusive linked list Next field 72 // Whether or not the criterion is met (True if met) 73 bool ready; 74 75 // The monitor this criterion concerns 76 monitor_desc * target; 77 78 // The parent node to which this criterion belongs 79 struct __condition_node_t * owner; 80 81 // Intrusive linked list Next field 82 __condition_criterion_t * next; 80 83 }; 81 84 82 85 struct __condition_node_t { 83 thread_desc * waiting_thread; //Thread that needs to be woken when all criteria are met 84 __condition_criterion_t * criteria; //Array of criteria (Criterions are contiguous in memory) 85 unsigned short count; //Number of criterions in the criteria 86 __condition_node_t * next; //Intrusive linked list Next field 87 uintptr_t user_info; //Custom user info accessible before signalling 86 // Thread that needs to be woken when all criteria are met 87 thread_desc * waiting_thread; 88 89 // Array of criteria (Criterions are contiguous in memory) 90 __condition_criterion_t * criteria; 91 92 // Number of criterions in the criteria 93 __lock_size_t count; 94 95 // Intrusive linked list Next field 96 __condition_node_t * next; 97 98 // Custom user info accessible before signalling 99 uintptr_t user_info; 88 100 }; 89 101 … … 93 105 }; 94 106 95 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info );107 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ); 96 108 void ?{}(__condition_criterion_t & this ); 97 109 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner ); 98 110 99 111 void ?{}( __condition_blocked_queue_t & ); 100 void append( __condition_blocked_queue_t *, __condition_node_t * );101 __condition_node_t * pop_head( __condition_blocked_queue_t *);112 void append( __condition_blocked_queue_t &, __condition_node_t * ); 113 __condition_node_t * pop_head( __condition_blocked_queue_t & ); 102 114 103 115 struct condition { 104 __condition_blocked_queue_t blocked; //Link list which contains the blocked threads as-well as the information needed to unblock them 105 monitor_desc ** monitors; //Array of monitor pointers (Monitors are NOT contiguous in memory) 106 unsigned short monitor_count; //Number of monitors in the array 116 // Link list which contains the blocked threads as-well as the information needed to unblock them 117 __condition_blocked_queue_t blocked; 118 119 // Array of monitor pointers (Monitors are NOT contiguous in memory) 120 monitor_desc ** monitors; 121 122 // Number of monitors in the array 123 __lock_size_t monitor_count; 107 124 }; 108 125 … … 116 133 } 117 134 118 void wait( condition *this, uintptr_t user_info = 0 );119 bool signal( condition *this );120 bool signal_block( condition *this );121 static inline bool is_empty ( condition * this ) { return !this->blocked.head; }122 uintptr_t front( condition *this );135 void wait ( condition & this, uintptr_t user_info = 0 ); 136 bool signal ( condition & this ); 137 bool signal_block( condition & this ); 138 static inline bool is_empty ( condition & this ) { return !this.blocked.head; } 139 uintptr_t front ( condition & this ); 123 140 124 141 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor.c
rf5c3b6c r0fe4e62 17 17 18 18 #include <stdlib> 19 #include <inttypes.h> 19 20 20 21 #include "libhdr.h" … … 26 27 // Forward declarations 27 28 static inline void set_owner ( monitor_desc * this, thread_desc * owner ); 28 static inline void set_owner ( monitor_desc * * storage, short count, thread_desc * owner );29 static inline void set_mask ( monitor_desc * * storage, short count, const __waitfor_mask_t & mask );29 static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner ); 30 static inline void set_mask ( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask ); 30 31 static inline void reset_mask( monitor_desc * this ); 31 32 … … 33 34 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors ); 34 35 35 static inline void lock_all ( spinlock ** locks, unsigned short count );36 static inline void lock_all ( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );37 static inline void unlock_all( spinlock ** locks, unsigned short count );38 static inline void unlock_all( monitor_desc * * locks, unsigned short count );39 40 static inline void save ( monitor_desc * * ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks);41 static inline void restore( monitor_desc * * ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks);42 43 static inline void init ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria);44 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria);36 static inline void lock_all ( __spinlock_t * locks [], __lock_size_t count ); 37 static inline void lock_all ( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ); 38 static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count ); 39 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ); 40 41 static inline void save ( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] ); 42 static inline void restore( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] ); 43 44 static inline void init ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ); 45 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ); 45 46 46 47 static inline thread_desc * check_condition ( __condition_criterion_t * ); 47 static inline void brand_condition ( condition *);48 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * * monitors, int count );48 static inline void brand_condition ( condition & ); 49 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count ); 49 50 50 51 forall(dtype T | sized( T )) 51 static inline short insert_unique( T ** array, short & size, T * val ); 52 static inline short count_max ( const __waitfor_mask_t & mask ); 53 static inline short aggregate ( monitor_desc ** storage, const __waitfor_mask_t & mask ); 52 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ); 53 static inline __lock_size_t count_max ( const __waitfor_mask_t & mask ); 54 static inline __lock_size_t aggregate ( monitor_desc * storage [], const __waitfor_mask_t & mask ); 55 56 #ifndef __CFA_LOCK_NO_YIELD 57 #define DO_LOCK lock_yield 58 #else 59 #define DO_LOCK lock 60 #endif 54 61 55 62 //----------------------------------------------------------------------------- … … 58 65 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 59 66 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 60 init( count, monitors, &waiter, criteria );/* Link everything together */ \67 init( count, monitors, waiter, criteria ); /* Link everything together */ \ 61 68 62 69 #define wait_ctx_primed(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 63 70 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 64 71 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 65 init_push( count, monitors, &waiter, criteria );/* Link everything together and push it to the AS-Stack */ \72 init_push( count, monitors, waiter, criteria ); /* Link everything together and push it to the AS-Stack */ \ 66 73 67 74 #define monitor_ctx( mons, cnt ) /* Define that create the necessary struct for internal/external scheduling operations */ \ 68 75 monitor_desc ** monitors = mons; /* Save the targeted monitors */ \ 69 unsigned short count = cnt;/* Save the count to a local variable */ \76 __lock_size_t count = cnt; /* Save the count to a local variable */ \ 70 77 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 71 __waitfor_mask_t masks [ count ];/* Save the current waitfor masks to restore them later */ \72 spinlock * locks[ count ]; /* We need to pass-in an array of locks to BlockInternal */ \78 __waitfor_mask_t masks [ count ]; /* Save the current waitfor masks to restore them later */ \ 79 __spinlock_t * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 73 80 74 81 #define monitor_save save ( monitors, count, locks, recursions, masks ) … … 83 90 // Enter single monitor 84 91 static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) { 85 // Lock the monitor spinlock , lock_yield to reduce contention86 lock_yield( &this->lock DEBUG_CTX2 );92 // Lock the monitor spinlock 93 DO_LOCK( this->lock DEBUG_CTX2 ); 87 94 thread_desc * thrd = this_thread; 88 95 … … 114 121 115 122 // Some one else has the monitor, wait in line for it 116 append( &this->entry_queue, thrd );123 append( this->entry_queue, thrd ); 117 124 BlockInternal( &this->lock ); 118 125 … … 126 133 127 134 // Release the lock and leave 128 unlock( &this->lock );135 unlock( this->lock ); 129 136 return; 130 137 } 131 138 132 139 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) { 133 // Lock the monitor spinlock , lock_yield to reduce contention134 lock_yield( &this->lock DEBUG_CTX2 );140 // Lock the monitor spinlock 141 DO_LOCK( this->lock DEBUG_CTX2 ); 135 142 thread_desc * thrd = this_thread; 136 143 … … 144 151 set_owner( this, thrd ); 145 152 146 unlock( &this->lock );153 unlock( this->lock ); 147 154 return; 148 155 } … … 153 160 } 154 161 155 int count = 1;162 __lock_size_t count = 1; 156 163 monitor_desc ** monitors = &this; 157 164 __monitor_group_t group = { &this, 1, func }; … … 160 167 161 168 // Wake the thread that is waiting for this 162 __condition_criterion_t * urgent = pop( &this->signal_stack );169 __condition_criterion_t * urgent = pop( this->signal_stack ); 163 170 verify( urgent ); 164 171 … … 182 189 183 190 // Some one else has the monitor, wait in line for it 184 append( &this->entry_queue, thrd );191 append( this->entry_queue, thrd ); 185 192 BlockInternal( &this->lock ); 186 193 … … 195 202 // Leave single monitor 196 203 void __leave_monitor_desc( monitor_desc * this ) { 197 // Lock the monitor spinlock, lock_yieldto reduce contention198 lock_yield( &this->lock DEBUG_CTX2 );204 // Lock the monitor spinlock, DO_LOCK to reduce contention 205 DO_LOCK( this->lock DEBUG_CTX2 ); 199 206 200 207 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); … … 209 216 if( this->recursion != 0) { 210 217 LIB_DEBUG_PRINT_SAFE("Kernel : recursion still %d\n", this->recursion); 211 unlock( &this->lock );218 unlock( this->lock ); 212 219 return; 213 220 } … … 217 224 218 225 // We can now let other threads in safely 219 unlock( &this->lock );226 unlock( this->lock ); 220 227 221 228 //We need to wake-up the thread … … 242 249 243 250 // Lock the monitor now 244 lock_yield( &this->lock DEBUG_CTX2 );251 DO_LOCK( this->lock DEBUG_CTX2 ); 245 252 246 253 disable_interrupts(); … … 272 279 // relies on the monitor array being sorted 273 280 static inline void enter( __monitor_group_t monitors ) { 274 for( int i = 0; i < monitors.size; i++) {281 for( __lock_size_t i = 0; i < monitors.size; i++) { 275 282 __enter_monitor_desc( monitors.list[i], monitors ); 276 283 } … … 279 286 // Leave multiple monitor 280 287 // relies on the monitor array being sorted 281 static inline void leave(monitor_desc * * monitors, int count) {282 for( int i = count - 1; i >= 0; i--) {288 static inline void leave(monitor_desc * monitors [], __lock_size_t count) { 289 for( __lock_size_t i = count - 1; i >= 0; i--) { 283 290 __leave_monitor_desc( monitors[i] ); 284 291 } … … 287 294 // Ctor for monitor guard 288 295 // Sorts monitors before entering 289 void ?{}( monitor_guard_t & this, monitor_desc * * m, int count, fptr_t func ) {296 void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) { 290 297 // Store current array 291 298 this.m = m; … … 296 303 297 304 // Save previous thread context 298 this.prev_mntrs = this_thread->monitors.list; 299 this.prev_count = this_thread->monitors.size; 300 this.prev_func = this_thread->monitors.func; 305 this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func]; 301 306 302 307 // Update thread context (needed for conditions) 303 this_thread->monitors.list = m; 304 this_thread->monitors.size = count; 305 this_thread->monitors.func = func; 308 this_thread->monitors.[list, size, func] = [m, count, func]; 306 309 307 310 // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count); … … 325 328 326 329 // Restore thread context 327 this_thread->monitors.list = this.prev_mntrs; 328 this_thread->monitors.size = this.prev_count; 329 this_thread->monitors.func = this.prev_func; 330 } 331 330 this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func]; 331 } 332 332 333 333 // Ctor for monitor guard 334 334 // Sorts monitors before entering 335 void ?{}( monitor_dtor_guard_t & this, monitor_desc * * m, fptr_t func ) {335 void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) { 336 336 // Store current array 337 337 this.m = *m; 338 338 339 339 // Save previous thread context 340 this.prev_mntrs = this_thread->monitors.list; 341 this.prev_count = this_thread->monitors.size; 342 this.prev_func = this_thread->monitors.func; 340 this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func]; 343 341 344 342 // Update thread context (needed for conditions) 345 this_thread->monitors.list = m; 346 this_thread->monitors.size = 1; 347 this_thread->monitors.func = func; 343 this_thread->monitors.[list, size, func] = [m, 1, func]; 348 344 349 345 __enter_monitor_dtor( this.m, func ); 350 346 } 351 352 347 353 348 // Dtor for monitor guard … … 357 352 358 353 // Restore thread context 359 this_thread->monitors.list = this.prev_mntrs; 360 this_thread->monitors.size = this.prev_count; 361 this_thread->monitors.func = this.prev_func; 354 this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func]; 362 355 } 363 356 364 357 //----------------------------------------------------------------------------- 365 358 // Internal scheduling types 366 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {359 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) { 367 360 this.waiting_thread = waiting_thread; 368 361 this.count = count; … … 378 371 } 379 372 380 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t *owner ) {373 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t & owner ) { 381 374 this.ready = false; 382 375 this.target = target; 383 this.owner = owner;376 this.owner = &owner; 384 377 this.next = NULL; 385 378 } … … 387 380 //----------------------------------------------------------------------------- 388 381 // Internal scheduling 389 void wait( condition *this, uintptr_t user_info = 0 ) {382 void wait( condition & this, uintptr_t user_info = 0 ) { 390 383 brand_condition( this ); 391 384 392 385 // Check that everything is as expected 393 assertf( this ->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );394 verifyf( this ->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );395 verifyf( this ->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );386 assertf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors ); 387 verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count ); 388 verifyf( this.monitor_count < 32u, "Excessive monitor count (%"PRIiFAST16")", this.monitor_count ); 396 389 397 390 // Create storage for monitor context 398 monitor_ctx( this ->monitors, this->monitor_count );391 monitor_ctx( this.monitors, this.monitor_count ); 399 392 400 393 // Create the node specific to this wait operation … … 403 396 // Append the current wait operation to the ones already queued on the condition 404 397 // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion 405 append( &this->blocked, &waiter );398 append( this.blocked, &waiter ); 406 399 407 400 // Lock all monitors (aggregates the locks as well) … … 409 402 410 403 // Find the next thread(s) to run 411 short thread_count = 0;404 __lock_size_t thread_count = 0; 412 405 thread_desc * threads[ count ]; 413 406 __builtin_memset( threads, 0, sizeof( threads ) ); … … 417 410 418 411 // Remove any duplicate threads 419 for( int i = 0; i < count; i++) {412 for( __lock_size_t i = 0; i < count; i++) { 420 413 thread_desc * new_owner = next_thread( monitors[i] ); 421 414 insert_unique( threads, thread_count, new_owner ); … … 429 422 } 430 423 431 bool signal( condition *this ) {424 bool signal( condition & this ) { 432 425 if( is_empty( this ) ) { return false; } 433 426 434 427 //Check that everything is as expected 435 verify( this ->monitors );436 verify( this ->monitor_count != 0 );428 verify( this.monitors ); 429 verify( this.monitor_count != 0 ); 437 430 438 431 //Some more checking in debug 439 432 LIB_DEBUG_DO( 440 433 thread_desc * this_thrd = this_thread; 441 if ( this ->monitor_count != this_thrd->monitors.size ) {442 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->monitors.size );443 } 444 445 for(int i = 0; i < this ->monitor_count; i++) {446 if ( this ->monitors[i] != this_thrd->monitors.list[i] ) {447 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->monitors.list[i] );434 if ( this.monitor_count != this_thrd->monitors.size ) { 435 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", &this, this.monitor_count, this_thrd->monitors.size ); 436 } 437 438 for(int i = 0; i < this.monitor_count; i++) { 439 if ( this.monitors[i] != this_thrd->monitors.list[i] ) { 440 abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors.list[i] ); 448 441 } 449 442 } 450 443 ); 451 444 452 unsigned short count = this->monitor_count;445 __lock_size_t count = this.monitor_count; 453 446 454 447 // Lock all monitors 455 lock_all( this ->monitors, NULL, count );448 lock_all( this.monitors, NULL, count ); 456 449 457 450 //Pop the head of the waiting queue 458 __condition_node_t * node = pop_head( &this->blocked );451 __condition_node_t * node = pop_head( this.blocked ); 459 452 460 453 //Add the thread to the proper AS stack … … 462 455 __condition_criterion_t * crit = &node->criteria[i]; 463 456 assert( !crit->ready ); 464 push( &crit->target->signal_stack, crit );457 push( crit->target->signal_stack, crit ); 465 458 } 466 459 467 460 //Release 468 unlock_all( this ->monitors, count );461 unlock_all( this.monitors, count ); 469 462 470 463 return true; 471 464 } 472 465 473 bool signal_block( condition *this ) {474 if( !this ->blocked.head ) { return false; }466 bool signal_block( condition & this ) { 467 if( !this.blocked.head ) { return false; } 475 468 476 469 //Check that everything is as expected 477 verifyf( this ->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );478 verifyf( this ->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );470 verifyf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors ); 471 verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count ); 479 472 480 473 // Create storage for monitor context 481 monitor_ctx( this ->monitors, this->monitor_count );474 monitor_ctx( this.monitors, this.monitor_count ); 482 475 483 476 // Lock all monitors (aggregates the locks them as well) … … 491 484 492 485 //Find the thread to run 493 thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;486 thread_desc * signallee = pop_head( this.blocked )->waiting_thread; 494 487 set_owner( monitors, count, signallee ); 495 488 496 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", this, signallee );489 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee ); 497 490 498 491 //Everything is ready to go to sleep … … 512 505 513 506 // Access the user_info of the thread waiting at the front of the queue 514 uintptr_t front( condition *this ) {507 uintptr_t front( condition & this ) { 515 508 verifyf( !is_empty(this), 516 509 "Attempt to access user data on an empty condition.\n" 517 510 "Possible cause is not checking if the condition is empty before reading stored data." 518 511 ); 519 return this ->blocked.head->user_info;512 return this.blocked.head->user_info; 520 513 } 521 514 … … 537 530 // This statment doesn't have a contiguous list of monitors... 538 531 // Create one! 539 short max = count_max( mask );532 __lock_size_t max = count_max( mask ); 540 533 monitor_desc * mon_storage[max]; 541 534 __builtin_memset( mon_storage, 0, sizeof( mon_storage ) ); 542 short actual_count = aggregate( mon_storage, mask );543 544 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, ( short)max);535 __lock_size_t actual_count = aggregate( mon_storage, mask ); 536 537 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max); 545 538 546 539 if(actual_count == 0) return; … … 569 562 570 563 __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria; 571 push( &mon2dtor->signal_stack, dtor_crit );564 push( mon2dtor->signal_stack, dtor_crit ); 572 565 573 566 unlock_all( locks, count ); … … 629 622 set_mask( monitors, count, mask ); 630 623 631 for( int i = 0; i < count; i++) {624 for( __lock_size_t i = 0; i < count; i++) { 632 625 verify( monitors[i]->owner == this_thread ); 633 626 } … … 661 654 } 662 655 663 static inline void set_owner( monitor_desc * * monitors, short count, thread_desc * owner ) {656 static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) { 664 657 monitors[0]->owner = owner; 665 658 monitors[0]->recursion = 1; 666 for( int i = 1; i < count; i++ ) {659 for( __lock_size_t i = 1; i < count; i++ ) { 667 660 monitors[i]->owner = owner; 668 661 monitors[i]->recursion = 0; … … 670 663 } 671 664 672 static inline void set_mask( monitor_desc * * storage, short count, const __waitfor_mask_t & mask ) {673 for( int i = 0; i < count; i++) {665 static inline void set_mask( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask ) { 666 for( __lock_size_t i = 0; i < count; i++) { 674 667 storage[i]->mask = mask; 675 668 } … … 685 678 //Check the signaller stack 686 679 LIB_DEBUG_PRINT_SAFE("Kernel : mon %p AS-stack top %p\n", this, this->signal_stack.top); 687 __condition_criterion_t * urgent = pop( &this->signal_stack );680 __condition_criterion_t * urgent = pop( this->signal_stack ); 688 681 if( urgent ) { 689 682 //The signaller stack is not empty, … … 697 690 // No signaller thread 698 691 // Get the next thread in the entry_queue 699 thread_desc * new_owner = pop_head( &this->entry_queue );692 thread_desc * new_owner = pop_head( this->entry_queue ); 700 693 set_owner( this, new_owner ); 701 694 … … 705 698 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) { 706 699 __acceptable_t * it = this->mask.clauses; // Optim 707 int count = this->mask.size;700 __lock_size_t count = this->mask.size; 708 701 709 702 // Check if there are any acceptable functions … … 714 707 715 708 // For all acceptable functions check if this is the current function. 716 for( short i = 0; i < count; i++, it++ ) {709 for( __lock_size_t i = 0; i < count; i++, it++ ) { 717 710 if( *it == group ) { 718 711 *this->mask.accepted = i; … … 725 718 } 726 719 727 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria) {728 for( int i = 0; i < count; i++) {720 static inline void init( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) { 721 for( __lock_size_t i = 0; i < count; i++) { 729 722 (criteria[i]){ monitors[i], waiter }; 730 723 } 731 724 732 waiter ->criteria = criteria;733 } 734 735 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria) {736 for( int i = 0; i < count; i++) {725 waiter.criteria = criteria; 726 } 727 728 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) { 729 for( __lock_size_t i = 0; i < count; i++) { 737 730 (criteria[i]){ monitors[i], waiter }; 738 731 LIB_DEBUG_PRINT_SAFE( "Kernel : target %p = %p\n", criteria[i].target, &criteria[i] ); 739 push( &criteria[i].target->signal_stack, &criteria[i] );740 } 741 742 waiter ->criteria = criteria;743 } 744 745 static inline void lock_all( spinlock ** locks, unsigned short count ) {746 for( int i = 0; i < count; i++ ) {747 lock_yield(locks[i] DEBUG_CTX2 );748 } 749 } 750 751 static inline void lock_all( monitor_desc * * source, spinlock ** /*out*/ locks, unsigned short count ) {752 for( int i = 0; i < count; i++ ) {753 spinlock* l = &source[i]->lock;754 lock_yield(l DEBUG_CTX2 );732 push( criteria[i].target->signal_stack, &criteria[i] ); 733 } 734 735 waiter.criteria = criteria; 736 } 737 738 static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) { 739 for( __lock_size_t i = 0; i < count; i++ ) { 740 DO_LOCK( *locks[i] DEBUG_CTX2 ); 741 } 742 } 743 744 static inline void lock_all( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ) { 745 for( __lock_size_t i = 0; i < count; i++ ) { 746 __spinlock_t * l = &source[i]->lock; 747 DO_LOCK( *l DEBUG_CTX2 ); 755 748 if(locks) locks[i] = l; 756 749 } 757 750 } 758 751 759 static inline void unlock_all( spinlock ** locks, unsigned short count ) { 760 for( int i = 0; i < count; i++ ) { 761 unlock( locks[i] ); 762 } 763 } 764 765 static inline void unlock_all( monitor_desc ** locks, unsigned short count ) { 766 for( int i = 0; i < count; i++ ) { 767 unlock( &locks[i]->lock ); 768 } 769 } 770 771 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 772 for( int i = 0; i < count; i++ ) { 752 static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count ) { 753 for( __lock_size_t i = 0; i < count; i++ ) { 754 unlock( *locks[i] ); 755 } 756 } 757 758 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) { 759 for( __lock_size_t i = 0; i < count; i++ ) { 760 unlock( locks[i]->lock ); 761 } 762 } 763 764 static inline void save( 765 monitor_desc * ctx [], 766 __lock_size_t count, 767 __attribute((unused)) __spinlock_t * locks [], 768 unsigned int /*out*/ recursions [], 769 __waitfor_mask_t /*out*/ masks [] 770 ) { 771 for( __lock_size_t i = 0; i < count; i++ ) { 773 772 recursions[i] = ctx[i]->recursion; 774 773 masks[i] = ctx[i]->mask; … … 776 775 } 777 776 778 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 777 static inline void restore( 778 monitor_desc * ctx [], 779 __lock_size_t count, 780 __spinlock_t * locks [], 781 unsigned int /*out*/ recursions [], 782 __waitfor_mask_t /*out*/ masks [] 783 ) { 779 784 lock_all( locks, count ); 780 for( int i = 0; i < count; i++ ) {785 for( __lock_size_t i = 0; i < count; i++ ) { 781 786 ctx[i]->recursion = recursions[i]; 782 787 ctx[i]->mask = masks[i]; … … 811 816 } 812 817 813 static inline void brand_condition( condition *this ) {818 static inline void brand_condition( condition & this ) { 814 819 thread_desc * thrd = this_thread; 815 if( !this ->monitors ) {820 if( !this.monitors ) { 816 821 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 817 822 assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list ); 818 this ->monitor_count = thrd->monitors.size;819 820 this ->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );821 for( int i = 0; i < this ->monitor_count; i++ ) {822 this ->monitors[i] = thrd->monitors.list[i];823 } 824 } 825 } 826 827 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * * monitors, int count ) {828 829 __thread_queue_t * entry_queue = &monitors[0]->entry_queue;823 this.monitor_count = thrd->monitors.size; 824 825 this.monitors = malloc( this.monitor_count * sizeof( *this.monitors ) ); 826 for( int i = 0; i < this.monitor_count; i++ ) { 827 this.monitors[i] = thrd->monitors.list[i]; 828 } 829 } 830 } 831 832 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * monitors [], __lock_size_t count ) { 833 834 __thread_queue_t & entry_queue = monitors[0]->entry_queue; 830 835 831 836 // For each thread in the entry-queue 832 for( thread_desc ** thrd_it = &entry_queue ->head;837 for( thread_desc ** thrd_it = &entry_queue.head; 833 838 *thrd_it; 834 839 thrd_it = &(*thrd_it)->next … … 852 857 853 858 forall(dtype T | sized( T )) 854 static inline short insert_unique( T ** array, short & size, T * val ) {859 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) { 855 860 if( !val ) return size; 856 861 857 for( int i = 0; i <= size; i++) {862 for( __lock_size_t i = 0; i <= size; i++) { 858 863 if( array[i] == val ) return size; 859 864 } … … 864 869 } 865 870 866 static inline short count_max( const __waitfor_mask_t & mask ) {867 short max = 0;868 for( int i = 0; i < mask.size; i++ ) {871 static inline __lock_size_t count_max( const __waitfor_mask_t & mask ) { 872 __lock_size_t max = 0; 873 for( __lock_size_t i = 0; i < mask.size; i++ ) { 869 874 max += mask.clauses[i].size; 870 875 } … … 872 877 } 873 878 874 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) {875 short size = 0;876 for( int i = 0; i < mask.size; i++ ) {879 static inline __lock_size_t aggregate( monitor_desc * storage [], const __waitfor_mask_t & mask ) { 880 __lock_size_t size = 0; 881 for( __lock_size_t i = 0; i < mask.size; i++ ) { 877 882 __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size ); 878 for( int j = 0; j < mask.clauses[i].size; j++) {883 for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) { 879 884 insert_unique( storage, size, mask.clauses[i].list[j] ); 880 885 } … … 890 895 } 891 896 892 void append( __condition_blocked_queue_t *this, __condition_node_t * c ) {893 verify(this ->tail != NULL);894 *this ->tail = c;895 this ->tail = &c->next;896 } 897 898 __condition_node_t * pop_head( __condition_blocked_queue_t *this ) {899 __condition_node_t * head = this ->head;897 void append( __condition_blocked_queue_t & this, __condition_node_t * c ) { 898 verify(this.tail != NULL); 899 *this.tail = c; 900 this.tail = &c->next; 901 } 902 903 __condition_node_t * pop_head( __condition_blocked_queue_t & this ) { 904 __condition_node_t * head = this.head; 900 905 if( head ) { 901 this ->head = head->next;906 this.head = head->next; 902 907 if( !head->next ) { 903 this ->tail = &this->head;908 this.tail = &this.head; 904 909 } 905 910 head->next = NULL; -
src/libcfa/concurrency/preemption.c
rf5c3b6c r0fe4e62 355 355 case SI_KERNEL: 356 356 // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 357 lock( &event_kernel->lock DEBUG_CTX2 );357 lock( event_kernel->lock DEBUG_CTX2 ); 358 358 tick_preemption(); 359 unlock( &event_kernel->lock );359 unlock( event_kernel->lock ); 360 360 break; 361 361 // Signal was not sent by the kernel but by an other thread -
src/main.cc
rf5c3b6c r0fe4e62 206 206 FILE * extras = fopen( libcfap | treep ? "../prelude/extras.cf" : CFA_LIBDIR "/extras.cf", "r" ); 207 207 assertf( extras, "cannot open extras.cf\n" ); 208 parse( extras, LinkageSpec:: C );208 parse( extras, LinkageSpec::BuiltinC ); 209 209 210 210 if ( ! libcfap ) { -
src/prelude/builtins.c
rf5c3b6c r0fe4e62 80 80 } // ?\? 81 81 82 static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); double ?/?( double, T ); } ) 83 double ?\?( T x, signed long int y ) { 84 if ( y >= 0 ) return (double)(x \ (unsigned long int)y); 85 else return 1.0 / x \ (unsigned long int)(-y); 86 } // ?\? 82 // FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither 83 // defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify 84 // X as a type that casts to double, yet it doesn't make sense to write functions with that type 85 // signature where X is double. 86 87 // static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); double ?/?( double, T ); } ) 88 // double ?\?( T x, signed long int y ) { 89 // if ( y >= 0 ) return (double)(x \ (unsigned long int)y); 90 // else return 1.0 / x \ (unsigned long int)(-y); 91 // } // ?\? 87 92 88 93 static inline long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; } -
src/tests/.expect/32/KRfunctions.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __f0__Fi_iPCii__1(signed int __a__i_1, const signed int *__b__PCi_1, signed int __c__i_1){ 8 2 __attribute__ ((unused)) signed int ___retval_f0__i_1; -
src/tests/.expect/32/attributes.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __la__Fi___1(){ 8 2 __attribute__ ((unused)) signed int ___retval_la__i_1; -
src/tests/.expect/32/declarationSpecifier.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 volatile const signed short int __x1__CVs_1; 8 2 static volatile const signed short int __x2__CVs_1; … … 701 695 } 702 696 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 703 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);704 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);705 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);706 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));707 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);708 extern signed int printf(const char *__restrict __format, ...);709 697 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 710 698 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/32/extension.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 __extension__ signed int __a__i_1; 8 2 __extension__ signed int __b__i_1; -
src/tests/.expect/32/gccExtensions.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 extern signed int __x__i_1 asm ( "xx" ); 8 2 signed int __main__Fi_iPPCc__1(signed int __argc__i_1, const char **__argv__PPCc_1){ … … 174 168 } 175 169 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 176 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);177 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);178 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);179 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));180 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);181 extern signed int printf(const char *__restrict __format, ...);182 170 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 183 171 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/32/literals.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 void __for_each__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object0)(), void *__anonymous_object1), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object2)(), void *__anonymous_object3), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object4)(), void *__anonymous_object5, void *__anonymous_object6), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object7)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object8), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object9)(), void *__anonymous_object10, void *__anonymous_object11), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object12)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object13, void *__anonymous_object14), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object15)(), void *__anonymous_object16, void *__anonymous_object17), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object18)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object19, void *__anonymous_object20), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object21, void *__anonymous_object22), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object23), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object24, void *__anonymous_object25), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object26), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object27, void *__anonymous_object28), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object29), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object30, void *__anonymous_object31), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object32), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object33), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object34), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object35, void *__anonymous_object36), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object37, void *__anonymous_object38), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object39), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object40)); 8 2 void __for_each_reverse__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object41)(), void *__anonymous_object42), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object43)(), void *__anonymous_object44), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object45)(), void *__anonymous_object46, void *__anonymous_object47), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object48)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object49), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object50)(), void *__anonymous_object51, void *__anonymous_object52), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object53)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object54, void *__anonymous_object55), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object56)(), void *__anonymous_object57, void *__anonymous_object58), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object59)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object60, void *__anonymous_object61), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object62, void *__anonymous_object63), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object64), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object65, void *__anonymous_object66), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object67), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object68, void *__anonymous_object69), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object70), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object71, void *__anonymous_object72), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object73), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object74), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object75), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object76, void *__anonymous_object77), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object78, void *__anonymous_object79), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object80), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object81)); … … 1377 1371 } 1378 1372 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } 1379 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);1380 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);1381 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);1382 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));1383 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);1384 extern signed int printf(const char *__restrict __format, ...);1385 1373 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 1386 1374 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/64/KRfunctions.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __f0__Fi_iPCii__1(signed int __a__i_1, const signed int *__b__PCi_1, signed int __c__i_1){ 8 2 __attribute__ ((unused)) signed int ___retval_f0__i_1; -
src/tests/.expect/64/attributes.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __la__Fi___1(){ 8 2 __attribute__ ((unused)) signed int ___retval_la__i_1; -
src/tests/.expect/64/declarationSpecifier.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 volatile const signed short int __x1__CVs_1; 8 2 static volatile const signed short int __x2__CVs_1; … … 701 695 } 702 696 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 703 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);704 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);705 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);706 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));707 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);708 extern signed int printf(const char *__restrict __format, ...);709 697 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 710 698 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/64/extension.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 __extension__ signed int __a__i_1; 8 2 __extension__ signed int __b__i_1; -
src/tests/.expect/64/gccExtensions.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 extern signed int __x__i_1 asm ( "xx" ); 8 2 signed int __main__Fi_iPPCc__1(signed int __argc__i_1, const char **__argv__PPCc_1){ … … 174 168 } 175 169 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 176 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);177 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);178 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);179 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));180 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);181 extern signed int printf(const char *__restrict __format, ...);182 170 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 183 171 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/64/literals.txt
rf5c3b6c r0fe4e62 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 void __for_each__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object0)(), void *__anonymous_object1), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object2)(), void *__anonymous_object3), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object4)(), void *__anonymous_object5, void *__anonymous_object6), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object7)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object8), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object9)(), void *__anonymous_object10, void *__anonymous_object11), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object12)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object13, void *__anonymous_object14), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object15)(), void *__anonymous_object16, void *__anonymous_object17), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object18)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object19, void *__anonymous_object20), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object21, void *__anonymous_object22), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object23), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object24, void *__anonymous_object25), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object26), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object27, void *__anonymous_object28), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object29), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object30, void *__anonymous_object31), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object32), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object33), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object34), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object35, void *__anonymous_object36), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object37, void *__anonymous_object38), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object39), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object40)); 8 2 void __for_each_reverse__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object41)(), void *__anonymous_object42), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object43)(), void *__anonymous_object44), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object45)(), void *__anonymous_object46, void *__anonymous_object47), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object48)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object49), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object50)(), void *__anonymous_object51, void *__anonymous_object52), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object53)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object54, void *__anonymous_object55), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object56)(), void *__anonymous_object57, void *__anonymous_object58), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object59)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object60, void *__anonymous_object61), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object62, void *__anonymous_object63), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object64), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object65, void *__anonymous_object66), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object67), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object68, void *__anonymous_object69), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object70), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object71, void *__anonymous_object72), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object73), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object74), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object75), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object76, void *__anonymous_object77), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object78, void *__anonymous_object79), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object80), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object81)); … … 1377 1371 } 1378 1372 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } 1379 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);1380 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);1381 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);1382 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));1383 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);1384 extern signed int printf(const char *__restrict __format, ...);1385 1373 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 1386 1374 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/boundedBuffer.c
rf5c3b6c r0fe4e62 1 // 1 // 2 2 // The contents of this file are covered under the licence agreement in the 3 3 // file "LICENCE" distributed with Cforall. 4 // 5 // boundedBuffer.c -- 6 // 4 // 5 // boundedBuffer.c -- 6 // 7 7 // Author : Peter A. Buhr 8 8 // Created On : Mon Oct 30 12:45:13 2017 … … 10 10 // Last Modified On : Mon Oct 30 23:02:46 2017 11 11 // Update Count : 9 12 // 12 // 13 13 14 14 #include <stdlib> … … 31 31 32 32 void insert( Buffer & mutex buffer, int elem ) { 33 if ( buffer.count == 20 ) wait( &buffer.empty );33 if ( buffer.count == 20 ) wait( buffer.empty ); 34 34 buffer.elements[buffer.back] = elem; 35 35 buffer.back = ( buffer.back + 1 ) % 20; 36 36 buffer.count += 1; 37 signal( &buffer.full );37 signal( buffer.full ); 38 38 } 39 39 int remove( Buffer & mutex buffer ) { 40 if ( buffer.count == 0 ) wait( &buffer.full );40 if ( buffer.count == 0 ) wait( buffer.full ); 41 41 int elem = buffer.elements[buffer.front]; 42 42 buffer.front = ( buffer.front + 1 ) % 20; 43 43 buffer.count -= 1; 44 signal( &buffer.empty );44 signal( buffer.empty ); 45 45 return elem; 46 46 } -
src/tests/datingService.c
rf5c3b6c r0fe4e62 1 // -*- Mode: C -*- 2 // 1 // -*- Mode: C -*- 2 // 3 3 // The contents of this file are covered under the licence agreement in the 4 4 // file "LICENCE" distributed with Cforall. 5 // 6 // datingService.c -- 7 // 5 // 6 // datingService.c -- 7 // 8 8 // Author : Peter A. Buhr 9 9 // Created On : Mon Oct 30 12:56:20 2017 … … 11 11 // Last Modified On : Mon Oct 30 23:02:11 2017 12 12 // Update Count : 15 13 // 13 // 14 14 15 15 #include <stdlib> // random … … 18 18 #include <thread> 19 19 #include <unistd.h> // getpid 20 21 bool empty( condition & c ) {22 return c.blocked.head == NULL;23 }24 20 25 21 enum { NoOfPairs = 20 }; … … 31 27 32 28 unsigned int girl( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) { 33 if ( empty( ds.Boys[ccode] ) ) {34 wait( &ds.Girls[ccode] );29 if ( is_empty( ds.Boys[ccode] ) ) { 30 wait( ds.Girls[ccode] ); 35 31 ds.GirlPhoneNo = PhoneNo; 36 32 } else { 37 33 ds.GirlPhoneNo = PhoneNo; 38 signal_block( &ds.Boys[ccode] );34 signal_block( ds.Boys[ccode] ); 39 35 } // if 40 36 return ds.BoyPhoneNo; … … 42 38 43 39 unsigned int boy( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) { 44 if ( empty( ds.Girls[ccode] ) ) {45 wait( &ds.Boys[ccode] );40 if ( is_empty( ds.Girls[ccode] ) ) { 41 wait( ds.Boys[ccode] ); 46 42 ds.BoyPhoneNo = PhoneNo; 47 43 } else { 48 44 ds.BoyPhoneNo = PhoneNo; 49 signal_block( &ds.Girls[ccode] );45 signal_block( ds.Girls[ccode] ); 50 46 } // if 51 47 return ds.GirlPhoneNo; -
src/tests/sched-int-barge.c
rf5c3b6c r0fe4e62 73 73 if( action == c.do_wait1 || action == c.do_wait2 ) { 74 74 c.state = WAIT; 75 wait( &cond );75 wait( cond ); 76 76 77 77 if(c.state != SIGNAL) { … … 83 83 c.state = SIGNAL; 84 84 85 signal( &cond );86 signal( &cond );85 signal( cond ); 86 signal( cond ); 87 87 } 88 88 else { -
src/tests/sched-int-block.c
rf5c3b6c r0fe4e62 47 47 //------------------------------------------------------------------------------ 48 48 void wait_op( global_data_t & mutex a, global_data_t & mutex b, unsigned i ) { 49 wait( &cond, (uintptr_t)this_thread );49 wait( cond, (uintptr_t)this_thread ); 50 50 51 51 yield( random( 10 ) ); … … 74 74 [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = this_thread; 75 75 76 if( !is_empty( &cond ) ) {76 if( !is_empty( cond ) ) { 77 77 78 thread_desc * next = front( &cond );78 thread_desc * next = front( cond ); 79 79 80 if( ! signal_block( &cond ) ) {80 if( ! signal_block( cond ) ) { 81 81 sout | "ERROR expected to be able to signal" | endl; 82 82 abort(); -
src/tests/sched-int-disjoint.c
rf5c3b6c r0fe4e62 59 59 // Waiting logic 60 60 bool wait( global_t & mutex m, global_data_t & mutex d ) { 61 wait( &cond );61 wait( cond ); 62 62 if( d.state != SIGNAL ) { 63 63 sout | "ERROR barging!" | endl; … … 80 80 //------------------------------------------------------------------------------ 81 81 // Signalling logic 82 void signal( condition *cond, global_t & mutex a, global_data_t & mutex b ) {82 void signal( condition & cond, global_t & mutex a, global_data_t & mutex b ) { 83 83 b.state = SIGNAL; 84 84 signal( cond ); … … 86 86 87 87 void logic( global_t & mutex a ) { 88 signal( &cond, a, data );88 signal( cond, a, data ); 89 89 90 90 yield( random( 10 ) ); -
src/tests/sched-int-wait.c
rf5c3b6c r0fe4e62 41 41 //---------------------------------------------------------------------------------------------------- 42 42 // Tools 43 void signal( condition *cond, global_t & mutex a, global_t & mutex b ) {43 void signal( condition & cond, global_t & mutex a, global_t & mutex b ) { 44 44 signal( cond ); 45 45 } 46 46 47 void signal( condition *cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {47 void signal( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) { 48 48 signal( cond ); 49 49 } 50 50 51 void wait( condition *cond, global_t & mutex a, global_t & mutex b ) {51 void wait( condition & cond, global_t & mutex a, global_t & mutex b ) { 52 52 wait( cond ); 53 53 } 54 54 55 void wait( condition *cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {55 void wait( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) { 56 56 wait( cond ); 57 57 } … … 65 65 switch( action ) { 66 66 case 0: 67 signal( &condABC, globalA, globalB, globalC );67 signal( condABC, globalA, globalB, globalC ); 68 68 break; 69 69 case 1: 70 signal( &condAB , globalA, globalB );70 signal( condAB , globalA, globalB ); 71 71 break; 72 72 case 2: 73 signal( &condBC , globalB, globalC );73 signal( condBC , globalB, globalC ); 74 74 break; 75 75 case 3: 76 signal( &condAC , globalA, globalC );76 signal( condAC , globalA, globalC ); 77 77 break; 78 78 default: … … 88 88 void main( WaiterABC & this ) { 89 89 for( int i = 0; i < N; i++ ) { 90 wait( &condABC, globalA, globalB, globalC );90 wait( condABC, globalA, globalB, globalC ); 91 91 } 92 92 … … 98 98 void main( WaiterAB & this ) { 99 99 for( int i = 0; i < N; i++ ) { 100 wait( &condAB , globalA, globalB );100 wait( condAB , globalA, globalB ); 101 101 } 102 102 … … 108 108 void main( WaiterAC & this ) { 109 109 for( int i = 0; i < N; i++ ) { 110 wait( &condAC , globalA, globalC );110 wait( condAC , globalA, globalC ); 111 111 } 112 112 … … 118 118 void main( WaiterBC & this ) { 119 119 for( int i = 0; i < N; i++ ) { 120 wait( &condBC , globalB, globalC );120 wait( condBC , globalB, globalC ); 121 121 } 122 122 -
src/tests/thread.c
rf5c3b6c r0fe4e62 15 15 yield(); 16 16 } 17 V( this.lock);17 V(*this.lock); 18 18 } 19 19 20 20 void main(Second& this) { 21 P( this.lock);21 P(*this.lock); 22 22 for(int i = 0; i < 10; i++) { 23 23 sout | "Second : Suspend No." | i + 1 | endl;
Note:
See TracChangeset
for help on using the changeset viewer.