Changeset 94b1022a


Ignore:
Timestamp:
May 30, 2018, 9:28:18 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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, with_gc
Children:
bd946e4
Parents:
35718a9 (diff), ae32d96 (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.
Message:

Merge branch 'master' of plg2:software/cfa/cfa-cc

Location:
src
Files:
2 added
1 deleted
33 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r35718a9 r94b1022a  
    172172        // *** Declarations
    173173        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
     174                // deleted decls should never be used, so don't print them
     175                if ( functionDecl->isDeleted && genC ) return;
    174176                extension( functionDecl );
    175177                genAttributes( functionDecl->get_attributes() );
     
    185187                        functionDecl->get_statements()->accept( *visitor );
    186188                } // if
     189                if ( functionDecl->isDeleted ) {
     190                        output << " = void";
     191                }
    187192        }
    188193
    189194        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
     195                // deleted decls should never be used, so don't print them
     196                if ( objectDecl->isDeleted && genC ) return;
    190197                if (objectDecl->get_name().empty() && genC ) {
    191198                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     
    206213                        objectDecl->get_init()->accept( *visitor );
    207214                } // if
     215                if ( objectDecl->isDeleted ) {
     216                        output << " = void";
     217                }
    208218
    209219                if ( objectDecl->get_bitfieldWidth() ) {
     
    827837                expr->expr->accept( *visitor );
    828838        }
     839
     840        void CodeGenerator::postvisit( GenericExpr * expr ) {
     841                assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     842                output << "_Generic(";
     843                expr->control->accept( *visitor );
     844                output << ", ";
     845                unsigned int numAssocs = expr->associations.size();
     846                unsigned int i = 0;
     847                for ( GenericExpr::Association & assoc : expr->associations ) {
     848                        if (assoc.isDefault) {
     849                                output << "default: ";
     850                        } else {
     851                                output << genType( assoc.type, "", pretty, genC ) << ": ";
     852                        }
     853                        assoc.expr->accept( *visitor );
     854                        if ( i+1 != numAssocs ) {
     855                                output << ", ";
     856                        }
     857                        i++;
     858                }
     859                output << ")";
     860        }
     861
    829862
    830863        // *** Statements
  • src/CodeGen/CodeGenerator.h

    r35718a9 r94b1022a  
    9494                void postvisit( ConstructorExpr * );
    9595                void postvisit( DeletedExpr * );
     96                void postvisit( GenericExpr * );
    9697
    9798                //*** Statements
  • src/Common/PassVisitor.h

    r35718a9 r94b1022a  
    125125        virtual void visit( InitExpr *  initExpr ) override final;
    126126        virtual void visit( DeletedExpr *  delExpr ) override final;
     127        virtual void visit( GenericExpr * genExpr ) override final;
    127128
    128129        virtual void visit( VoidType * basicType ) override final;
     
    223224        virtual Expression * mutate( InitExpr *  initExpr ) override final;
    224225        virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
     226        virtual Expression * mutate( GenericExpr * genExpr ) override final;
    225227
    226228        virtual Type * mutate( VoidType * basicType ) override final;
     
    311313        void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    312314        void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
    313         void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith     ( pass, 0, exprs, withStmt ); }
     315        void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
    314316
    315317
  • src/Common/PassVisitor.impl.h

    r35718a9 r94b1022a  
    20732073
    20742074//--------------------------------------------------------------------------
     2075// GenericExpr
     2076template< typename pass_type >
     2077void PassVisitor< pass_type >::visit( GenericExpr * node ) {
     2078        VISIT_START( node );
     2079
     2080        indexerScopedAccept( node->result, *this );
     2081        maybeAccept_impl( node->control, *this );
     2082        for ( GenericExpr::Association & assoc : node->associations ) {
     2083                indexerScopedAccept( assoc.type, *this );
     2084                maybeAccept_impl( assoc.expr, *this );
     2085        }
     2086
     2087        VISIT_END( node );
     2088}
     2089
     2090template< typename pass_type >
     2091Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
     2092        MUTATE_START( node );
     2093
     2094        indexerScopedMutate( node->env, *this );
     2095        indexerScopedMutate( node->result, *this );
     2096        maybeMutate_impl( node->control, *this );
     2097        for ( GenericExpr::Association & assoc : node->associations ) {
     2098                indexerScopedMutate( assoc.type, *this );
     2099                maybeMutate_impl( assoc.expr, *this );
     2100        }
     2101
     2102        MUTATE_END( Expression, node );
     2103}
     2104
     2105//--------------------------------------------------------------------------
    20752106// VoidType
    20762107template< typename pass_type >
  • src/Concurrency/Keywords.cc

    r35718a9 r94b1022a  
    443443                bool first = false;
    444444                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first );
    445                 if( mutexArgs.empty() ) return;
    446 
    447                 if( CodeGen::isConstructor(decl->name) && first ) SemanticError( decl, "constructors cannot have mutex parameters" );
    448 
    449445                bool isDtor = CodeGen::isDestructor( decl->name );
    450446
     447                // Is this function relevant to monitors
     448                if( mutexArgs.empty() ) {
     449                        // If this is the destructor for a monitor it must be mutex
     450                        if(isDtor) {
     451                                Type* ty = decl->get_functionType()->get_parameters().front()->get_type();
     452
     453                                // If it's a copy, it's not a mutex
     454                                ReferenceType* rty = dynamic_cast< ReferenceType * >( ty );
     455                                if( ! rty ) return;
     456
     457                                // If we are not pointing directly to a type, it's not a mutex
     458                                Type* base = rty->get_base();
     459                                if( dynamic_cast< ReferenceType * >( base ) ) return;
     460                                if( dynamic_cast< PointerType * >( base ) ) return;
     461
     462                                // Check if its a struct
     463                                StructInstType * baseStruct = dynamic_cast< StructInstType * >( base );
     464                                if( !baseStruct ) return;
     465
     466                                // Check if its a monitor
     467                                if(baseStruct->baseStruct->is_monitor() || baseStruct->baseStruct->is_thread())
     468                                        SemanticError( decl, "destructors for structures declared as \"monitor\" must use mutex parameters\n" );
     469                        }
     470                        return;
     471                }
     472
     473                // Monitors can't be constructed with mutual exclusion
     474                if( CodeGen::isConstructor(decl->name) && !first ) SemanticError( decl, "constructors cannot have mutex parameters" );
     475
     476                // It makes no sense to have multiple mutex parameters for the destructor
    451477                if( isDtor && mutexArgs.size() != 1 ) SemanticError( decl, "destructors can only have 1 mutex argument" );
    452478
     479                // Make sure all the mutex arguments are monitors
    453480                for(auto arg : mutexArgs) {
    454481                        validate( arg );
    455482                }
    456483
     484                // Check if we need to instrument the body
    457485                CompoundStmt* body = decl->get_statements();
    458486                if( ! body ) return;
    459487
     488                // Do we have the required headers
    460489                if( !monitor_decl || !guard_decl || !dtor_guard_decl )
    461                         SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>" );
    462 
     490                        SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>\n" );
     491
     492                // Instrument the body
    463493                if( isDtor ) {
    464494                        addDtorStatments( decl, body, mutexArgs );
  • src/Parser/DeclarationNode.cc

    r35718a9 r94b1022a  
    10671067                        SemanticError( this, "invalid function specifier for " );
    10681068                } // if
    1069                 return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     1069                bool isDelete = initializer && initializer->get_isDelete();
     1070                Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     1071                if ( isDelete ) {
     1072                        DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
     1073                        dwt->isDeleted = true;
     1074                }
     1075                return decl;
    10701076        } // if
    10711077
  • src/Parser/InitializerNode.cc

    r35718a9 r94b1022a  
    2727
    2828InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des )
    29                 : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {
     29                : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) {
    3030        if ( aggrp )
    3131                kids = dynamic_cast< InitializerNode * >( get_next() );
     
    3636
    3737InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des )
    38                 : expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {
     38                : expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) {
    3939        if ( init )
    4040                set_last( init );
     
    4646                set_next( nullptr );
    4747} // InitializerNode::InitializerNode
     48
     49InitializerNode::InitializerNode( bool isDelete ) : expr( nullptr ), aggregate( false ), designator( nullptr ), kids( nullptr ), maybeConstructed( false ), isDelete( isDelete ) {}
    4850
    4951InitializerNode::~InitializerNode() {
     
    8486
    8587Initializer * InitializerNode::build() const {
     88        assertf( ! isDelete, "Should not build delete stmt InitializerNode" );
    8689        if ( aggregate ) {
    8790                // steal designators from children
  • src/Parser/ParseNode.h

    r35718a9 r94b1022a  
    8787        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
    8888        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
     89        InitializerNode( bool isDelete );
    8990        ~InitializerNode();
    9091        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
     
    9798        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
    9899        bool get_maybeConstructed() const { return maybeConstructed; }
     100
     101        bool get_isDelete() const { return isDelete; }
    99102
    100103        InitializerNode * next_init() const { return kids; }
     
    110113        InitializerNode * kids;
    111114        bool maybeConstructed;
     115        bool isDelete;
    112116}; // InitializerNode
    113117
  • src/Parser/TypeData.cc

    r35718a9 r94b1022a  
    6565          case Aggregate:
    6666                // aggregate = new Aggregate_t;
     67                aggregate.kind = DeclarationNode::NoAggregate;
    6768                aggregate.name = nullptr;
    6869                aggregate.params = nullptr;
     
    7071                aggregate.fields = nullptr;
    7172                aggregate.body = false;
     73                aggregate.tagged = false;
     74                aggregate.parent = nullptr;
    7275                break;
    7376          case AggregateInst:
     
    198201                break;
    199202          case Aggregate:
     203                newtype->aggregate.kind = aggregate.kind;
    200204                newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
    201205                newtype->aggregate.params = maybeClone( aggregate.params );
    202206                newtype->aggregate.actuals = maybeClone( aggregate.actuals );
    203207                newtype->aggregate.fields = maybeClone( aggregate.fields );
    204                 newtype->aggregate.kind = aggregate.kind;
    205208                newtype->aggregate.body = aggregate.body;
    206209                newtype->aggregate.tagged = aggregate.tagged;
  • src/Parser/parser.yy

    r35718a9 r94b1022a  
    175175        bool flag;
    176176        CatchStmt::Kind catch_kind;
     177        GenericExpr * genexpr;
    177178}
    178179
     
    259260%type<flag> asm_volatile_opt
    260261%type<en> handler_predicate_opt
     262%type<genexpr> generic_association generic_assoc_list
    261263
    262264// statements
     
    501503                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    502504        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    503                 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     505                {
     506                        // add the missing control expression to the GenericExpr and return it
     507                        $5->control = maybeMoveBuild<Expression>( $3 );
     508                        $$ = new ExpressionNode( $5 );
     509                }
    504510        ;
    505511
    506512generic_assoc_list:                                                                             // C11
    507         | generic_association
     513        generic_association
    508514        | generic_assoc_list ',' generic_association
     515                {
     516                        // steal the association node from the singleton and delete the wrapper
     517                        $1->associations.splice($1->associations.end(), $3->associations);
     518                        delete $3;
     519                        $$ = $1;
     520                }
    509521        ;
    510522
    511523generic_association:                                                                    // C11
    512524        type_no_function ':' assignment_expression
     525                {
     526                        // create a GenericExpr wrapper with one association pair
     527                        $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>($3) } } );
     528                }
    513529        | DEFAULT ':' assignment_expression
     530                { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>($3) } } ); }
    514531        ;
    515532
     
    20812098                { $$ = $2; }
    20822099        | '=' VOID
    2083                 { $$ = nullptr; }
     2100                { $$ = new InitializerNode( true ); }
    20842101        | ATassign initializer
    20852102                { $$ = $2->set_maybeConstructed( false ); }
  • src/ResolvExpr/AlternativeFinder.cc

    r35718a9 r94b1022a  
    9797                void postvisit( InitExpr * initExpr );
    9898                void postvisit( DeletedExpr * delExpr );
     99                void postvisit( GenericExpr * genExpr );
    99100
    100101                /// Adds alternatives for anonymous members
     
    17561757                assertf( false, "AlternativeFinder should never see a DeletedExpr." );
    17571758        }
     1759
     1760        void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
     1761                assertf( false, "_Generic is not yet supported." );
     1762        }
    17581763} // namespace ResolvExpr
    17591764
  • src/SymTab/Indexer.cc

    r35718a9 r94b1022a  
    148148                for ( auto decl : copy ) {
    149149                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
    150                                 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
     150                                std::list< DeclarationWithType * > & params = function->type->parameters;
    151151                                assert( ! params.empty() );
    152152                                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     
    170170                                bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    171171                                bool isUserDefinedFunc = ball.isUserDefinedFunc;
    172                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
     172                                bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->linkage == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    173173                                bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    174174                                bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
     
    471471        void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
    472472                // default handling of conflicts is to raise an error
    473                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr );
     473                addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
    474474        }
    475475
  • src/SymTab/Mangler.cc

    r35718a9 r94b1022a  
    171171                                        "w",    // SignedInt128
    172172                                        "Uw",   // UnsignedInt128
    173                                         "a",   // Float80
    174                                         "A",   // Float128
     173                                        "x",   // Float80
     174                                        "y",   // Float128
    175175                                };
    176176                                static_assert(
     
    225225                                GuardValue( inFunctionType );
    226226                                inFunctionType = true;
    227                                 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
     227                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
    228228                                acceptAll( returnTypes, *visitor );
    229229                                mangleName << "_";
    230                                 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
     230                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
    231231                                acceptAll( paramTypes, *visitor );
    232232                                mangleName << "_";
     
    236236                                printQualifiers( refType );
    237237
    238                                 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
     238                                mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
    239239
    240240                                if ( mangleGenericParams ) {
    241                                         std::list< Expression* >& params = refType->get_parameters();
     241                                        std::list< Expression* >& params = refType->parameters;
    242242                                        if ( ! params.empty() ) {
    243243                                                mangleName << "_";
    244244                                                for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
    245245                                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    246                                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
    247                                                         maybeAccept( paramType->get_type(), *visitor );
     246                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
     247                                                        maybeAccept( paramType->type, *visitor );
    248248                                                }
    249249                                                mangleName << "_";
  • src/SynTree/Declaration.cc

    r35718a9 r94b1022a  
    104104}
    105105
     106
    106107// Local Variables: //
    107108// tab-width: 4 //
  • src/SynTree/Declaration.h

    r35718a9 r94b1022a  
    8484        Expression *asmName;
    8585        std::list< Attribute * > attributes;
     86        bool isDeleted = false;
    8687
    8788        DeclarationWithType( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, const std::list< Attribute * > & attributes, Type::FuncSpecifiers fs );
  • src/SynTree/Expression.cc

    r35718a9 r94b1022a  
    748748}
    749749
     750GenericExpr::Association::Association( Type * type, Expression * expr ) : type( type ), expr( expr ), isDefault( false ) {}
     751GenericExpr::Association::Association( Expression * expr ) : type( nullptr ), expr( expr ), isDefault( true ) {}
     752GenericExpr::Association::Association( const Association & other ) : type( maybeClone( other.type ) ), expr( maybeClone( other.expr ) ), isDefault( other.isDefault ) {}
     753GenericExpr::Association::~Association() {
     754        delete type;
     755        delete expr;
     756}
     757
     758GenericExpr::GenericExpr( Expression * control, const std::list<Association> & assoc ) : Expression(), control( control ), associations( assoc ) {}
     759GenericExpr::GenericExpr( const GenericExpr & other ) : Expression(other), control( maybeClone( other.control ) ), associations( other.associations ) {
     760}
     761GenericExpr::~GenericExpr() {
     762        delete control;
     763}
     764
     765void GenericExpr::print( std::ostream & os, Indenter indent ) const {
     766        os << "C11 _Generic Expression" << std::endl << indent+1;
     767        control->print( os, indent+1 );
     768        os << std::endl << indent+1 << "... with associations: " << std::endl;
     769        for ( const Association & assoc : associations ) {
     770                os << indent+1;
     771                if (assoc.isDefault) {
     772                        os << "... default: ";
     773                        assoc.expr->print( os, indent+1 );
     774                } else {
     775                        os << "... type: ";
     776                        assoc.type->print( os, indent+1 );
     777                        os << std::endl << indent+1 << "... expression: ";
     778                        assoc.expr->print( os, indent+1 );
     779                        os << std::endl;
     780                }
     781                os << std::endl;
     782        }
     783}
    750784
    751785// Local Variables: //
  • src/SynTree/Expression.h

    r35718a9 r94b1022a  
    865865};
    866866
     867/// C11 _Generic expression
     868class GenericExpr : public Expression {
     869public:
     870        struct Association {
     871                Type * type = nullptr;
     872                Expression * expr = nullptr;
     873                bool isDefault = false;
     874
     875                Association( Type * type, Expression * expr );
     876                Association( Expression * expr );
     877                Association( const Association & other );
     878                Association & operator=( const Association & other ) = delete; // at the moment this isn't used, and I don't want to implement it
     879                ~Association();
     880        };
     881
     882        Expression * control;
     883        std::list<Association> associations;
     884
     885        GenericExpr( Expression * control, const std::list<Association> & assoc );
     886        GenericExpr( const GenericExpr & other );
     887        virtual ~GenericExpr();
     888
     889        virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
     890        virtual void accept( Visitor & v ) { v.visit( this ); }
     891        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     892        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     893};
     894
    867895// Local Variables: //
    868896// tab-width: 4 //
  • src/SynTree/Mutator.h

    r35718a9 r94b1022a  
    9393        virtual Expression * mutate( InitExpr  * initExpr ) = 0;
    9494        virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
     95        virtual Expression * mutate( GenericExpr * genExpr ) = 0;
    9596
    9697        virtual Type * mutate( VoidType * basicType ) = 0;
  • src/SynTree/SynTree.h

    r35718a9 r94b1022a  
    101101class InitExpr;
    102102class DeletedExpr;
     103class GenericExpr;
    103104
    104105class Type;
  • src/SynTree/Visitor.h

    r35718a9 r94b1022a  
    9595        virtual void visit( InitExpr *  initExpr ) = 0;
    9696        virtual void visit( DeletedExpr * delExpr ) = 0;
     97        virtual void visit( GenericExpr * genExpr ) = 0;
    9798
    9899        virtual void visit( VoidType * basicType ) = 0;
  • src/benchmark/Makefile.am

    r35718a9 r94b1022a  
    277277
    278278compile-io$(EXEEXT):
    279         @${CC} -quiet -fsyntax-only -w ../tests/io.c                                    @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     279        @${CC} -quiet -fsyntax-only -w ../tests/io1.c                           @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    280280
    281281compile-monitor$(EXEEXT):
    282         @${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c            @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     282        @${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c    @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    283283
    284284compile-operators$(EXEEXT):
     
    289289
    290290compile-typeof$(EXEEXT):
    291         @${CC} -quiet -fsyntax-only -w ../tests/typeof.c                                @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    292 
     291        @${CC} -quiet -fsyntax-only -w ../tests/typeof.c                        @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     292
  • src/libcfa/Makefile.am

    r35718a9 r94b1022a  
    5151# not all platforms support concurrency, add option do disable it
    5252if BUILD_CONCURRENCY
    53 headers += concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor
     53headers += concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor concurrency/mutex
    5454endif
    5555
  • src/libcfa/Makefile.in

    r35718a9 r94b1022a  
    9797
    9898# not all platforms support concurrency, add option do disable it
    99 @BUILD_CONCURRENCY_TRUE@am__append_3 = concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor
     99@BUILD_CONCURRENCY_TRUE@am__append_3 = concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor concurrency/mutex
    100100
    101101# not all platforms support concurrency, add option do disable it
     
    153153        containers/pair.c containers/result.c containers/vector.c \
    154154        concurrency/coroutine.c concurrency/thread.c \
    155         concurrency/kernel.c concurrency/monitor.c assert.c \
    156         exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
    157         concurrency/alarm.c concurrency/invoke.c \
    158         concurrency/preemption.c
     155        concurrency/kernel.c concurrency/monitor.c concurrency/mutex.c \
     156        assert.c exception.c virtual.c \
     157        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
     158        concurrency/invoke.c concurrency/preemption.c
    159159am__dirstamp = $(am__leading_dot)dirstamp
    160160@BUILD_CONCURRENCY_TRUE@am__objects_1 = concurrency/libcfa_d_a-coroutine.$(OBJEXT) \
    161161@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-thread.$(OBJEXT) \
    162162@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-kernel.$(OBJEXT) \
    163 @BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-monitor.$(OBJEXT)
     163@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-monitor.$(OBJEXT) \
     164@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-mutex.$(OBJEXT)
    164165am__objects_2 = libcfa_d_a-fstream.$(OBJEXT) \
    165166        libcfa_d_a-iostream.$(OBJEXT) libcfa_d_a-iterator.$(OBJEXT) \
     
    188189        containers/result.c containers/vector.c \
    189190        concurrency/coroutine.c concurrency/thread.c \
    190         concurrency/kernel.c concurrency/monitor.c assert.c \
    191         exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
    192         concurrency/alarm.c concurrency/invoke.c \
    193         concurrency/preemption.c
     191        concurrency/kernel.c concurrency/monitor.c concurrency/mutex.c \
     192        assert.c exception.c virtual.c \
     193        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
     194        concurrency/invoke.c concurrency/preemption.c
    194195@BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
    195196@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-thread.$(OBJEXT) \
    196197@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-kernel.$(OBJEXT) \
    197 @BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-monitor.$(OBJEXT)
     198@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-monitor.$(OBJEXT) \
     199@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-mutex.$(OBJEXT)
    198200am__objects_6 = libcfa_a-fstream.$(OBJEXT) libcfa_a-iostream.$(OBJEXT) \
    199201        libcfa_a-iterator.$(OBJEXT) libcfa_a-limits.$(OBJEXT) \
     
    264266        containers/result containers/vector concurrency/coroutine \
    265267        concurrency/thread concurrency/kernel concurrency/monitor \
    266         ${shell find stdhdr -type f -printf "%p "} math gmp time_t.h \
    267         clock bits/align.h bits/containers.h bits/defs.h bits/debug.h \
    268         bits/locks.h concurrency/invoke.h
     268        concurrency/mutex ${shell find stdhdr -type f -printf "%p "} \
     269        math gmp time_t.h clock bits/align.h bits/containers.h \
     270        bits/defs.h bits/debug.h bits/locks.h concurrency/invoke.h
    269271HEADERS = $(nobase_cfa_include_HEADERS)
    270272am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     
    548550concurrency/libcfa_d_a-monitor.$(OBJEXT): concurrency/$(am__dirstamp) \
    549551        concurrency/$(DEPDIR)/$(am__dirstamp)
     552concurrency/libcfa_d_a-mutex.$(OBJEXT): concurrency/$(am__dirstamp) \
     553        concurrency/$(DEPDIR)/$(am__dirstamp)
    550554concurrency/CtxSwitch-@MACHINE_TYPE@.$(OBJEXT):  \
    551555        concurrency/$(am__dirstamp) \
     
    580584        concurrency/$(DEPDIR)/$(am__dirstamp)
    581585concurrency/libcfa_a-monitor.$(OBJEXT): concurrency/$(am__dirstamp) \
     586        concurrency/$(DEPDIR)/$(am__dirstamp)
     587concurrency/libcfa_a-mutex.$(OBJEXT): concurrency/$(am__dirstamp) \
    582588        concurrency/$(DEPDIR)/$(am__dirstamp)
    583589concurrency/libcfa_a-alarm.$(OBJEXT): concurrency/$(am__dirstamp) \
     
    635641@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-kernel.Po@am__quote@
    636642@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-monitor.Po@am__quote@
     643@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-mutex.Po@am__quote@
    637644@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-preemption.Po@am__quote@
    638645@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-thread.Po@am__quote@
     
    642649@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-kernel.Po@am__quote@
    643650@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-monitor.Po@am__quote@
     651@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-mutex.Po@am__quote@
    644652@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-preemption.Po@am__quote@
    645653@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-thread.Po@am__quote@
     
    930938@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
    931939
     940concurrency/libcfa_d_a-mutex.o: concurrency/mutex.c
     941@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-mutex.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo -c -o concurrency/libcfa_d_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     942@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_d_a-mutex.Po
     943@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_d_a-mutex.o' libtool=no @AMDEPBACKSLASH@
     944@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     945@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     946
     947concurrency/libcfa_d_a-mutex.obj: concurrency/mutex.c
     948@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-mutex.obj -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo -c -o concurrency/libcfa_d_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
     949@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_d_a-mutex.Po
     950@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_d_a-mutex.obj' libtool=no @AMDEPBACKSLASH@
     951@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     952@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
     953
    932954libcfa_d_a-assert.o: assert.c
    933955@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-assert.o -MD -MP -MF $(DEPDIR)/libcfa_d_a-assert.Tpo -c -o libcfa_d_a-assert.o `test -f 'assert.c' || echo '$(srcdir)/'`assert.c
     
    12371259@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    12381260@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
     1261
     1262concurrency/libcfa_a-mutex.o: concurrency/mutex.c
     1263@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_a-mutex.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo -c -o concurrency/libcfa_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     1264@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_a-mutex.Po
     1265@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_a-mutex.o' libtool=no @AMDEPBACKSLASH@
     1266@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1267@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     1268
     1269concurrency/libcfa_a-mutex.obj: concurrency/mutex.c
     1270@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_a-mutex.obj -MD -MP -MF concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo -c -o concurrency/libcfa_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
     1271@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_a-mutex.Po
     1272@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_a-mutex.obj' libtool=no @AMDEPBACKSLASH@
     1273@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1274@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
    12391275
    12401276libcfa_a-assert.o: assert.c
  • src/libcfa/bits/containers.h

    r35718a9 r94b1022a  
    183183                verify( *tail == NULL );
    184184                return val;
     185        }
     186
     187        forall(dtype T | is_node(T))
     188        static inline bool ?!=?( __queue(T) & this, zero_t zero ) {
     189                return this.head != 0;
    185190        }
    186191#endif
     
    261266                __get( node ).prev = NULL;
    262267        }
     268
     269        forall(dtype T | sized(T))
     270        static inline bool ?!=?( __dllist(T) & this, zero_t zero ) {
     271                return this.head != 0;
     272        }
    263273        #undef next
    264274        #undef prev
  • src/libcfa/concurrency/kernel

    r35718a9 r94b1022a  
    2323extern "C" {
    2424#include <pthread.h>
     25#include <semaphore.h>
    2526}
    2627
     
    4344extern struct cluster * mainCluster;
    4445
    45 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule };
     46enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule, Callback };
     47
     48typedef void (*__finish_callback_fptr_t)(void);
    4649
    4750//TODO use union, many of these fields are mutually exclusive (i.e. MULTI vs NOMULTI)
    4851struct FinishAction {
    4952        FinishOpCode action_code;
     53        /*
     54        // Union of possible actions
     55        union {
     56                // Option 1 : locks and threads
     57                struct {
     58                        // 1 thread or N thread
     59                        union {
     60                                thread_desc * thrd;
     61                                struct {
     62                                        thread_desc ** thrds;
     63                                        unsigned short thrd_count;
     64                                };
     65                        };
     66                        // 1 lock or N lock
     67                        union {
     68                                __spinlock_t * lock;
     69                                struct {
     70                                        __spinlock_t ** locks;
     71                                        unsigned short lock_count;
     72                                };
     73                        };
     74                };
     75                // Option 2 : action pointer
     76                __finish_callback_fptr_t callback;
     77        };
     78        /*/
    5079        thread_desc * thrd;
     80        thread_desc ** thrds;
     81        unsigned short thrd_count;
    5182        __spinlock_t * lock;
    5283        __spinlock_t ** locks;
    5384        unsigned short lock_count;
    54         thread_desc ** thrds;
    55         unsigned short thrd_count;
     85        __finish_callback_fptr_t callback;
     86        //*/
    5687};
    5788static inline void ?{}(FinishAction & this) {
     
    101132
    102133        // Idle lock
     134        sem_t idleLock;
    103135
    104136        // Link lists fields
  • src/libcfa/concurrency/kernel.c

    r35718a9 r94b1022a  
    4949thread_desc * mainThread;
    5050
    51 struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
     51struct { __dllist_t(cluster) list; __spinlock_t lock; } global_clusters;
    5252
    5353//-----------------------------------------------------------------------------
     
    143143        runner.proc = &this;
    144144
     145        sem_init(&idleLock, 0, 0);
     146
    145147        start( &this );
    146148}
     
    156158                pthread_join( kernel_thread, NULL );
    157159        }
     160
     161        sem_destroy(&idleLock);
    158162}
    159163
     
    257261// its final actions must be executed from the kernel
    258262void finishRunning(processor * this) with( this->finish ) {
    259         if( action_code == Release ) {
    260                 verify( ! kernelTLS.preemption_state.enabled );
     263        verify( ! kernelTLS.preemption_state.enabled );
     264        choose( action_code ) {
     265        case No_Action:
     266                break;
     267        case Release:
    261268                unlock( *lock );
    262         }
    263         else if( action_code == Schedule ) {
     269        case Schedule:
    264270                ScheduleThread( thrd );
    265         }
    266         else if( action_code == Release_Schedule ) {
    267                 verify( ! kernelTLS.preemption_state.enabled );
     271        case Release_Schedule:
    268272                unlock( *lock );
    269273                ScheduleThread( thrd );
    270         }
    271         else if( action_code == Release_Multi ) {
    272                 verify( ! kernelTLS.preemption_state.enabled );
     274        case Release_Multi:
    273275                for(int i = 0; i < lock_count; i++) {
    274276                        unlock( *locks[i] );
    275277                }
    276         }
    277         else if( action_code == Release_Multi_Schedule ) {
     278        case Release_Multi_Schedule:
    278279                for(int i = 0; i < lock_count; i++) {
    279280                        unlock( *locks[i] );
     
    282283                        ScheduleThread( thrds[i] );
    283284                }
    284         }
    285         else {
    286                 assert(action_code == No_Action);
     285        case Callback:
     286                callback();
     287        default:
     288                abort("KERNEL ERROR: Unexpected action to run after thread");
    287289        }
    288290}
     
    291293// TODO : find some strategy to put cores to sleep after some time
    292294void spin(processor * this, unsigned int * spin_count) {
    293         (*spin_count)++;
     295        // (*spin_count)++;
     296        halt(this);
    294297}
    295298
     
    396399        with( *thrd->curr_cluster ) {
    397400                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
     401                bool was_empty = !(ready_queue != 0);
    398402                append( ready_queue, thrd );
    399403                unlock( ready_queue_lock );
     404
     405                if( was_empty ) {
     406                        lock      (proc_list_lock __cfaabi_dbg_ctx2);
     407                        if(idles) {
     408                                wake(idles.head);
     409                        }
     410                        unlock    (proc_list_lock);
     411                }
    400412        }
    401413
     
    497509}
    498510
     511void BlockInternal(__finish_callback_fptr_t callback) {
     512        disable_interrupts();
     513        with( *kernelTLS.this_processor ) {
     514                finish.action_code = Callback;
     515                finish.callback    = callback;
     516        }
     517
     518        verify( ! kernelTLS.preemption_state.enabled );
     519        returnToKernel();
     520        verify( ! kernelTLS.preemption_state.enabled );
     521
     522        enable_interrupts( __cfaabi_dbg_ctx );
     523}
     524
    499525// KERNEL ONLY
    500526void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
     
    627653//=============================================================================================
    628654
    629 // void halt(processor * this) with( this ) {
    630 //      pthread_mutex_lock( &idle.lock );
    631 
    632 
    633 
    634 //      // SKULLDUGGERY: Even if spurious wake-up is a thing
    635 //      // spuriously waking up a kernel thread is not a big deal
    636 //      // if it is very rare.
    637 //      pthread_cond_wait( &idle.cond, &idle.lock);
    638 //      pthread_mutex_unlock( &idle.lock );
    639 // }
    640 
    641 // void wake(processor * this) with( this ) {
    642 //      pthread_mutex_lock  (&idle.lock);
    643 //      pthread_cond_signal (&idle.cond);
    644 //      pthread_mutex_unlock(&idle.lock);
    645 // }
     655void halt(processor * this) with( *this ) {
     656        with( *cltr ) {
     657                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     658                remove    (procs, *this);
     659                push_front(idles, *this);
     660                unlock    (proc_list_lock);
     661        }
     662
     663        __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
     664
     665        sem_wait(&idleLock);
     666
     667        __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     668
     669        with( *cltr ) {
     670                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     671                remove    (idles, *this);
     672                push_front(procs, *this);
     673                unlock    (proc_list_lock);
     674        }
     675}
     676
     677void wake(processor * this) {
     678        __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);
     679        sem_post(&this->idleLock);
     680}
    646681
    647682//=============================================================================================
  • src/libcfa/concurrency/kernel_private.h

    r35718a9 r94b1022a  
    4848void BlockInternal(__spinlock_t * locks [], unsigned short count);
    4949void BlockInternal(__spinlock_t * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count);
     50void BlockInternal(__finish_callback_fptr_t callback);
    5051void LeaveThread(__spinlock_t * lock, thread_desc * thrd);
    5152
     
    5657void runThread(processor * this, thread_desc * dst);
    5758void finishRunning(processor * this);
     59void halt(processor * this);
     60void wake(processor * this);
    5861void terminate(processor * this);
    5962void spin(processor * this, unsigned int * spin_count);
  • src/libcfa/concurrency/monitor.c

    r35718a9 r94b1022a  
    297297        this.count = count;
    298298
    299         // Sort monitors based on address -> TODO use a sort specialized for small numbers
     299        // Sort monitors based on address
    300300        __libcfa_small_sort(this.m, count);
    301301
  • src/libcfa/concurrency/preemption.c

    r35718a9 r94b1022a  
    266266void terminate(processor * this) {
    267267        this->do_terminate = true;
     268        wake(this);
    268269        sigval_t value = { PREEMPT_TERMINATE };
    269270        pthread_sigqueue( this->kernel_thread, SIGUSR1, value );
  • src/tests/concurrent/signal/block.c

    r35718a9 r94b1022a  
    4040}
    4141
    42 void ^?{} ( global_data_t & this ) {}
     42void ^?{} ( global_data_t & mutex this ) {}
    4343
    4444global_data_t globalA, globalB;
  • src/tests/concurrent/signal/disjoint.c

    r35718a9 r94b1022a  
    2626monitor global_data_t;
    2727void ?{}( global_data_t & this );
    28 void ^?{} ( global_data_t & this );
     28void ^?{} ( global_data_t & mutex this );
    2929
    3030monitor global_data_t {
     
    4242}
    4343
    44 void ^?{} ( global_data_t & this ) {}
     44void ^?{} ( global_data_t & mutex this ) {}
    4545
    4646//------------------------------------------------------------------------------
  • src/tests/pybin/tools.py

    r35718a9 r94b1022a  
    8383        return sh(cmd)
    8484
     85def which(program):
     86    import os
     87    def is_exe(fpath):
     88        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
     89
     90    fpath, fname = os.path.split(program)
     91    if fpath:
     92        if is_exe(program):
     93            return program
     94    else:
     95        for path in os.environ["PATH"].split(os.pathsep):
     96            exe_file = os.path.join(path, program)
     97            if is_exe(exe_file):
     98                return exe_file
     99
     100    return None
    85101################################################################################
    86102#               file handling
     
    219235        return False
    220236
     237def fancy_print(text):
     238        column = which('column')
     239        if column:
     240                cmd = "%s 2> /dev/null" % column
     241                print(cmd)
     242                proc = Popen(cmd, stdin=PIPE, stderr=None, shell=True)
     243                proc.communicate(input=text)
     244        else:
     245                print(text)
    221246
    222247settings.set_machine_default( getMachineType )
  • src/tests/test.py

    r35718a9 r94b1022a  
    277277        elif options.list :
    278278                print("Listing for %s:%s"% (settings.arch.string, settings.debug.string))
    279                 print("\n".join(map(lambda t: "%s" % (t.toString()), tests)))
     279                fancy_print("\n".join(map(lambda t: "%s" % (t.toString()), tests)))
    280280
    281281        else :
Note: See TracChangeset for help on using the changeset viewer.