Changeset b3d70eb


Ignore:
Timestamp:
Apr 19, 2017, 10:31:57 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
12d3187, 4e9151f, 6a8ac0b
Parents:
5c3632f (diff), e3987770 (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

Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/concurrency/thePlan.md

    r5c3632f rb3d70eb  
    1010done - Multi monitors calls,
    1111done - Monitors as a language feature (not calling enter/leave by hand)
     12
     13_Phase 3_ : Monitor features
    1214Internal scheduling
     15External scheduling
    1316
    14 _Phase 3_ : Kernel features
     17_Phase 4_ : Kernel features
    1518Preemption
    1619Detach thread
    1720Cluster migration
    18 
    19 _Phase 4_ : Monitor features
    20 External scheduling
    2121
    2222_Phase 5_ : Performance
  • src/CodeGen/CodeGenerator.cc

    r5c3632f rb3d70eb  
    8989        }
    9090
    91         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ) {}
     91        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ) {}
    9292
    9393        CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp )
     
    136136                functionDecl->get_funcSpec().print( output );
    137137
    138                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty );
     138                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC );
    139139
    140140                asmName( functionDecl );
     
    147147
    148148        void CodeGenerator::visit( ObjectDecl * objectDecl ) {
    149                 if (objectDecl->get_name().empty()) {
     149                if (objectDecl->get_name().empty() && genC ) {
     150                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    150151                        static UniqueName name = { "__anonymous_object" };
    151152                        objectDecl->set_name( name.newName() );
     
    156157
    157158                handleStorageClass( objectDecl );
    158                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty );
     159                output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
    159160
    160161                asmName( objectDecl );
     
    171172        }
    172173
    173         void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) {
     174        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    174175                genAttributes( aggDecl->get_attributes() );
    175176
     177                if( ! aggDecl->get_parameters().empty() && ! genC ) {
     178                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
     179                        output << "forall(";
     180                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
     181                        output << ")" << endl;
     182                }
     183
     184                output << kind;
    176185                if ( aggDecl->get_name() != "" )
    177186                        output << aggDecl->get_name();
    178187
    179                 // std::list< Declaration * > & memb = aggDecl->get_members();
    180                 // if ( ! memb.empty() ) {
    181188                if ( aggDecl->has_body() ) {
    182189                        std::list< Declaration * > & memb = aggDecl->get_members();
     
    198205        void CodeGenerator::visit( StructDecl * structDecl ) {
    199206                extension( structDecl );
    200                 output << "struct ";
    201                 handleAggregate( structDecl );
     207                handleAggregate( structDecl, "struct " );
    202208        }
    203209
    204210        void CodeGenerator::visit( UnionDecl * unionDecl ) {
    205211                extension( unionDecl );
    206                 output << "union ";
    207                 handleAggregate( unionDecl );
     212                handleAggregate( unionDecl, "union " );
    208213        }
    209214
     
    242247
    243248        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
    244                 assert( false && "Typedefs are removed and substituted in earlier passes." );
    245                 //output << "typedef ";
    246                 //output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty );
     249                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
     250                output << "typedef ";
     251                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
    247252        }
    248253
    249254        void CodeGenerator::visit( TypeDecl * typeDecl ) {
    250                 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
    251                 // still to be done
    252                 extension( typeDecl );
    253                 output << "extern unsigned long " << typeDecl->get_name();
    254                 if ( typeDecl->get_base() ) {
    255                         output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty ) << " )";
    256                 } // if
     255                if ( genC ) {
     256                        // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     257                        // still to be done
     258                        extension( typeDecl );
     259                        output << "extern unsigned long " << typeDecl->get_name();
     260                        if ( typeDecl->get_base() ) {
     261                                output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty, genC ) << " )";
     262                        } // if
     263                } else {
     264                        output << typeDecl->typeString() << " " << typeDecl->get_name();
     265                        if ( ! typeDecl->get_assertions().empty() ) {
     266                                output << " | { ";
     267                                genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() );
     268                                output << " }";
     269                        }
     270                }
    257271        }
    258272
     
    293307
    294308        void CodeGenerator::visit( ConstructorInit * init ){
    295                 assertf( false, "ConstructorInit nodes should not make it to CodeGen." );
     309                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
     310                // xxx - generate something reasonable for constructor/destructor pairs
     311                output << "<ctorinit>";
    296312        }
    297313
     
    547563                        // at least one result type of cast, but not an lvalue
    548564                        output << "(";
    549                         output << genType( castExpr->get_result(), "", pretty );
     565                        output << genType( castExpr->get_result(), "", pretty, genC );
    550566                        output << ")";
    551567                } else {
     
    558574
    559575        void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
    560                 assert( false );
     576                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
     577                extension( memberExpr );
     578                memberExpr->get_aggregate()->accept( *this );
     579                output << ".";
     580                memberExpr->get_member()->accept( *this );
    561581        }
    562582
     
    587607                output << "sizeof(";
    588608                if ( sizeofExpr->get_isType() ) {
    589                         output << genType( sizeofExpr->get_type(), "", pretty );
     609                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    590610                } else {
    591611                        sizeofExpr->get_expr()->accept( *this );
     
    599619                output << "__alignof__(";
    600620                if ( alignofExpr->get_isType() ) {
    601                         output << genType( alignofExpr->get_type(), "", pretty );
     621                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    602622                } else {
    603623                        alignofExpr->get_expr()->accept( *this );
     
    607627
    608628        void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
    609                 assert( false && "UntypedOffsetofExpr should not reach code generation." );
     629                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
     630                output << "offsetof(";
     631                output << genType( offsetofExpr->get_type(), "", pretty, genC );
     632                output << ", " << offsetofExpr->get_member();
     633                output << ")";
    610634        }
    611635
     
    613637                // use GCC builtin
    614638                output << "__builtin_offsetof(";
    615                 output << genType( offsetofExpr->get_type(), "", pretty );
     639                output << genType( offsetofExpr->get_type(), "", pretty, genC );
    616640                output << ", " << mangleName( offsetofExpr->get_member() );
    617641                output << ")";
     
    619643
    620644        void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
    621                 assert( false && "OffsetPackExpr should not reach code generation." );
     645                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
     646                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    622647        }
    623648
     
    655680        }
    656681
    657         void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) { assertf( false, "UntypedTupleExpr should not make it to Code Gen" ); }
    658 
    659         void CodeGenerator::visit( TupleExpr * tupleExpr ) { assertf( false, "TupleExpr should not make it to Code Gen" ); }
    660 
    661         void CodeGenerator::visit( TypeExpr * typeExpr ) {}
     682        void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) {
     683                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
     684                output << "[";
     685                genCommaList( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end() );
     686                output << "]";
     687        }
     688
     689        void CodeGenerator::visit( TupleExpr * tupleExpr ) {
     690                assertf( ! genC, "TupleExpr should not reach code generation." );
     691                output << "[";
     692                genCommaList( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end() );
     693                output << "]";
     694        }
     695
     696        void CodeGenerator::visit( TypeExpr * typeExpr ) {
     697                assertf( ! genC, "TypeExpr should not reach code generation." );
     698                output<< genType( typeExpr->get_type(), "", pretty, genC );
     699        }
    662700
    663701        void CodeGenerator::visit( AsmExpr * asmExpr ) {
     
    675713        void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
    676714                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    677                 output << "(" << genType( compLitExpr->get_result(), "", pretty ) << ")";
     715                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    678716                compLitExpr->get_initializer()->accept( *this );
    679717        }
  • src/CodeGen/CodeGenerator.h

    r5c3632f rb3d70eb  
    3030                static int tabsize;
    3131
    32                 CodeGenerator( std::ostream &os, bool pretty = false );
     32                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false );
    3333                CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false );
    3434                CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
     
    121121                LabelPrinter printLabels;
    122122                bool pretty = false;  // pretty print
     123                bool genC = false;    // true if output has to be C code
    123124
    124125                void printDesignators( std::list< Expression * > & );
    125126                void handleStorageClass( DeclarationWithType *decl );
    126                 void handleAggregate( AggregateDecl *aggDecl );
     127                void handleAggregate( AggregateDecl *aggDecl, const std::string & kind );
    127128                void handleTypedef( NamedTypeDecl *namedType );
    128129                std::string mangleName( DeclarationWithType * decl );
  • src/CodeGen/GenType.cc

    r5c3632f rb3d70eb  
    2828        class GenType : public Visitor {
    2929          public:
    30                 GenType( const std::string &typeString, bool pretty = false );
     30                GenType( const std::string &typeString, bool pretty = false, bool genC = false );
    3131                std::string get_typeString() const { return typeString; }
    3232                void set_typeString( const std::string &newValue ) { typeString = newValue; }
     
    4848          private:
    4949                void handleQualifiers( Type *type );
     50                std::string handleGeneric( ReferenceToType * refType );
    5051                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    5152
    5253                std::string typeString;
    5354                bool pretty = false; // pretty print
     55                bool genC = false;   // generating C code?
    5456        };
    5557
    56         std::string genType( Type *type, const std::string &baseString, bool pretty ) {
    57                 GenType gt( baseString, pretty );
     58        std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC ) {
     59                GenType gt( baseString, pretty, genC );
    5860                std::ostringstream os;
    5961
    6062                if ( ! type->get_attributes().empty() ) {
    61                         CodeGenerator cg( os, pretty );
     63                        CodeGenerator cg( os, pretty, genC );
    6264                        cg.genAttributes( type->get_attributes() );
    6365                } // if
     
    6870
    6971  std::string genPrettyType( Type * type, const std::string & baseString ) {
    70         return genType( type, baseString, true );
     72        return genType( type, baseString, true, false );
    7173  }
    7274
    73         GenType::GenType( const std::string &typeString, bool pretty ) : typeString( typeString ), pretty( pretty ) {}
     75        GenType::GenType( const std::string &typeString, bool pretty, bool genC ) : typeString( typeString ), pretty( pretty ), genC( genC ) {}
    7476
    7577        void GenType::visit( VoidType *voidType ) {
     
    112114                } // if
    113115                if ( dimension != 0 ) {
    114                         CodeGenerator cg( os, pretty );
     116                        CodeGenerator cg( os, pretty, genC );
    115117                        dimension->accept( cg );
    116118                } else if ( isVarLen ) {
     
    166168                        } // if
    167169                } else {
    168                         CodeGenerator cg( os, pretty );
     170                        CodeGenerator cg( os, pretty, genC );
    169171                        os << "(" ;
    170172
     
    184186                        funcType->get_returnVals().front()->get_type()->accept( *this );
    185187                } // if
     188
     189                // add forall
     190                if( ! funcType->get_forall().empty() && ! genC ) {
     191                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
     192                        std::ostringstream os;
     193                        CodeGenerator cg( os, pretty, genC );
     194                        os << "forall(";
     195                        cg.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
     196                        os << ")" << std::endl;
     197                        typeString = os.str() + typeString;
     198                }
     199        }
     200
     201        std::string GenType::handleGeneric( ReferenceToType * refType ) {
     202                if ( ! refType->get_parameters().empty() ) {
     203                        std::ostringstream os;
     204                        CodeGenerator cg( os, pretty, genC );
     205                        os << "(";
     206                        cg.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
     207                        os << ") ";
     208                        return os.str();
     209                }
     210                return "";
    186211        }
    187212
    188213        void GenType::visit( StructInstType *structInst )  {
    189                 typeString = "struct " + structInst->get_name() + " " + typeString;
     214                typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString;
     215                if ( genC ) typeString = "struct " + typeString;
    190216                handleQualifiers( structInst );
    191217        }
    192218
    193219        void GenType::visit( UnionInstType *unionInst ) {
    194                 typeString = "union " + unionInst->get_name() + " " + typeString;
     220                typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString;
     221                if ( genC ) typeString = "union " + typeString;
    195222                handleQualifiers( unionInst );
    196223        }
    197224
    198225        void GenType::visit( EnumInstType *enumInst ) {
    199                 typeString = "enum " + enumInst->get_name() + " " + typeString;
     226                typeString = enumInst->get_name() + " " + typeString;
     227                if ( genC ) typeString = "enum " + typeString;
    200228                handleQualifiers( enumInst );
    201229        }
     
    207235
    208236        void GenType::visit( TupleType * tupleType ) {
    209                 assertf( pretty, "Tuple types should not make it to Code Gen." );
     237                assertf( ! genC, "Tuple types should not reach code generation." );
    210238                Visitor::visit( tupleType );
    211239                unsigned int i = 0;
     
    214242                for ( Type * t : *tupleType ) {
    215243                        i++;
    216                         os << genType( t, "", pretty ) << (i == tupleType->size() ? "" : ", ");
     244                        os << genType( t, "", pretty, genC ) << (i == tupleType->size() ? "" : ", ");
    217245                }
    218246                os << "]";
  • src/CodeGen/GenType.h

    r5c3632f rb3d70eb  
    2121
    2222namespace CodeGen {
    23         std::string genType( Type *type, const std::string &baseString, bool pretty = false );
     23        std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false );
    2424  std::string genPrettyType( Type * type, const std::string & baseString );
    2525} // namespace CodeGen
  • src/CodeGen/Generate.cc

    r5c3632f rb3d70eb  
    2727
    2828namespace CodeGen {
    29         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty ) {
    30                 CodeGen::CodeGenerator cgv( os, pretty );
     29        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC ) {
     30                CodeGen::CodeGenerator cgv( os, pretty, generateC );
    3131                for ( auto & dcl : translationUnit ) {
    3232                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
  • src/CodeGen/Generate.h

    r5c3632f rb3d70eb  
    2323
    2424namespace CodeGen {
    25         /// Generates code
    26         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty );
     25        /// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)
     26        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false );
    2727} // namespace CodeGen
    2828
  • src/SynTree/Declaration.h

    r5c3632f rb3d70eb  
    167167        std::list< DeclarationWithType* >& get_assertions() { return assertions; }
    168168
     169        virtual std::string typeString() const = 0;
     170
    169171        virtual NamedTypeDecl *clone() const = 0;
    170172        virtual void print( std::ostream &os, int indent = 0 ) const;
    171173        virtual void printShort( std::ostream &os, int indent = 0 ) const;
    172174  protected:
    173         virtual std::string typeString() const = 0;
    174175  private:
    175176        Type *base;
     
    202203        TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
    203204
     205        virtual std::string typeString() const;
     206
    204207        virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
    205208        virtual void accept( Visitor &v ) { v.visit( this ); }
    206209        virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    207210  private:
    208         virtual std::string typeString() const;
    209211        Kind kind;
    210212        bool sized;
     
    217219        TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    218220
     221        virtual std::string typeString() const;
     222
    219223        virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); }
    220224        virtual void accept( Visitor &v ) { v.visit( this ); }
    221225        virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    222226  private:
    223         virtual std::string typeString() const;
    224227};
    225228
  • src/libcfa/concurrency/invoke.h

    r5c3632f rb3d70eb  
    3333      };
    3434
    35       struct simple_thread_list {
     35      struct __thread_queue_t {
    3636            struct thread_desc * head;
    3737            struct thread_desc ** tail;
    3838      };
    3939
     40      struct __thread_stack_t {
     41            struct thread_desc * top;
     42      };
     43
    4044      #ifdef __CFORALL__
    4145      extern "Cforall" {
    42             void ?{}( struct simple_thread_list * );
    43             void append( struct simple_thread_list *, struct thread_desc * );
    44             struct thread_desc * pop_head( struct simple_thread_list * );
     46            void ?{}( struct __thread_queue_t * );
     47            void append( struct __thread_queue_t *, struct thread_desc * );
     48            struct thread_desc * pop_head( struct __thread_queue_t * );
     49
     50            void ?{}( struct __thread_stack_t * );
     51            void push( struct __thread_stack_t *, struct thread_desc * );           
     52            struct thread_desc * pop( struct __thread_stack_t * );
    4553
    4654            void ?{}(spinlock * this);
     
    5058
    5159      struct coStack_t {
    52             unsigned int size;                  // size of stack
    53             void *storage;                      // pointer to stack
    54             void *limit;                        // stack grows towards stack limit
    55             void *base;                         // base of stack
    56             void *context;                      // address of cfa_context_t
    57             void *top;                          // address of top of storage
    58             bool userStack;                     // whether or not the user allocated the stack
     60            unsigned int size;                        // size of stack
     61            void *storage;                            // pointer to stack
     62            void *limit;                              // stack grows towards stack limit
     63            void *base;                               // base of stack
     64            void *context;                            // address of cfa_context_t
     65            void *top;                                // address of top of storage
     66            bool userStack;                           // whether or not the user allocated the stack
    5967      };
    6068
     
    6270
    6371      struct coroutine_desc {
    64             struct coStack_t stack;             // stack information of the coroutine
    65             const char *name;                   // textual name for coroutine/task, initialized by uC++ generated code
    66             int errno_;                         // copy of global UNIX variable errno
    67             enum coroutine_state state;         // current execution status for coroutine
    68             struct coroutine_desc *starter;     // first coroutine to resume this one
    69             struct coroutine_desc *last;              // last coroutine to resume this one
     72            struct coStack_t stack;                   // stack information of the coroutine
     73            const char *name;                         // textual name for coroutine/task, initialized by uC++ generated code
     74            int errno_;                               // copy of global UNIX variable errno
     75            enum coroutine_state state;               // current execution status for coroutine
     76            struct coroutine_desc *starter;           // first coroutine to resume this one
     77            struct coroutine_desc *last;                    // last coroutine to resume this one
    7078      };
    7179
    7280      struct monitor_desc {
    73             struct spinlock lock;
    74             struct thread_desc * owner;
    75             struct simple_thread_list entry_queue;
    76             unsigned int recursion;
     81            struct spinlock lock;                     // spinlock to protect internal data
     82            struct thread_desc * owner;               // current owner of the monitor
     83            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
     84            struct __thread_stack_t signal_stack;     // stack of threads to run next once we exit the monitor
     85            struct monitor_desc * stack_owner;        // if bulk acquiring was used we need to synchronize signals with an other monitor
     86            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    7787      };
    7888
    7989      struct thread_desc {
    80             struct coroutine_desc cor;          // coroutine body used to store context
    81             struct monitor_desc mon;            // monitor body used for mutual exclusion
    82             struct thread_desc * next;          // instrusive link field for threads
     90            struct coroutine_desc cor;                // coroutine body used to store context
     91            struct monitor_desc mon;                  // monitor body used for mutual exclusion
     92            struct thread_desc * next;                // instrusive link field for threads
     93            struct monitor_desc ** current_monitors;  // currently held monitors
     94            unsigned short current_monitor_count;     // number of currently held monitors
    8395      };
    8496
  • src/libcfa/concurrency/kernel

    r5c3632f rb3d70eb  
    3232
    3333struct signal_once {
    34         volatile bool condition;
     34        volatile bool cond;
    3535        struct spinlock lock;
    36         struct simple_thread_list blocked;
     36        struct __thread_queue_t blocked;
    3737};
    3838
     
    4646// Cluster
    4747struct cluster {
    48         simple_thread_list ready_queue;
     48        __thread_queue_t ready_queue;
    4949        spinlock lock;
    5050};
  • src/libcfa/concurrency/kernel.c

    r5c3632f rb3d70eb  
    299299// Scheduler routines
    300300void ScheduleThread( thread_desc * thrd ) {
     301        if( !thrd ) return;
     302
    301303        assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
    302304       
     
    473475
    474476void ?{}( signal_once * this ) {
    475         this->condition = false;
     477        this->cond = false;
    476478}
    477479void ^?{}( signal_once * this ) {
     
    481483void wait( signal_once * this ) {
    482484        lock( &this->lock );
    483         if( !this->condition ) {
     485        if( !this->cond ) {
    484486                append( &this->blocked, this_thread() );
    485487                ScheduleInternal( &this->lock );
     
    492494        lock( &this->lock );
    493495        {
    494                 this->condition = true;
     496                this->cond = true;
    495497
    496498                thread_desc * it;
     
    504506//-----------------------------------------------------------------------------
    505507// Queues
    506 void ?{}( simple_thread_list * this ) {
     508void ?{}( __thread_queue_t * this ) {
    507509        this->head = NULL;
    508510        this->tail = &this->head;
    509511}
    510512
    511 void append( simple_thread_list * this, thread_desc * t ) {
     513void append( __thread_queue_t * this, thread_desc * t ) {
    512514        assert(this->tail != NULL);
    513515        *this->tail = t;
     
    515517}
    516518
    517 thread_desc * pop_head( simple_thread_list * this ) {
     519thread_desc * pop_head( __thread_queue_t * this ) {
    518520        thread_desc * head = this->head;
    519521        if( head ) {
     
    526528        return head;
    527529}
     530
     531void ?{}( __thread_stack_t * this ) {
     532        this->top = NULL;
     533}
     534
     535void push( __thread_stack_t * this, thread_desc * t ) {
     536        assert(t->next != NULL);
     537        t->next = this->top;
     538        this->top = t;
     539}
     540
     541thread_desc * pop( __thread_stack_t * this ) {
     542        thread_desc * top = this->top;
     543        if( top ) {
     544                this->top = top->next;
     545                top->next = NULL;
     546        }       
     547        return top;
     548}
    528549// Local Variables: //
    529550// mode: c //
  • src/libcfa/concurrency/monitor

    r5c3632f rb3d70eb  
    1818#define MONITOR_H
    1919
     20#include <stddef.h>
     21
    2022#include "assert"
    2123#include "invoke.h"
     
    2325
    2426static inline void ?{}(monitor_desc * this) {
    25         this->owner = 0;
     27        this->owner = NULL;
     28      this->stack_owner = NULL;
    2629        this->recursion = 0;
    2730}
    28 
    29 //Array entering routine
    30 void enter(monitor_desc **, int count);
    31 void leave(monitor_desc **, int count);
    3231
    3332struct monitor_guard_t {
    3433        monitor_desc ** m;
    3534        int count;
     35      monitor_desc ** prev_mntrs;
     36      unsigned short  prev_count;
    3637};
    3738
     
    4041}
    4142
    42 static inline void ?{}( monitor_guard_t * this, monitor_desc ** m, int count ) {
    43         this->m = m;
    44         this->count = count;
    45         qsort(this->m, count);
    46         enter( this->m, this->count );
     43void ?{}( monitor_guard_t * this, monitor_desc ** m, int count );
     44void ^?{}( monitor_guard_t * this );
     45
     46//-----------------------------------------------------------------------------
     47// Internal scheduling
     48struct condition {
     49        __thread_queue_t blocked;
     50        monitor_desc ** monitors;
     51        unsigned short monitor_count;
     52};
     53
     54static inline void ?{}( condition * this ) {
     55        this->monitors = NULL;
     56        this->monitor_count = 0;
    4757}
    4858
    49 static inline void ^?{}( monitor_guard_t * this ) {
    50         leave( this->m, this->count );
    51 }
    52 
    53 
     59void wait( condition * this );
     60void signal( condition * this );
    5461#endif //MONITOR_H
  • src/libcfa/concurrency/monitor.c

    r5c3632f rb3d70eb  
    1818
    1919#include "kernel_private.h"
     20#include "libhdr.h"
     21
     22void set_owner( monitor_desc * this, thread_desc * owner ) {
     23        //Pass the monitor appropriately
     24        this->owner = owner;
     25
     26        //We are passing the monitor to someone else, which means recursion level is not 0
     27        this->recursion = owner ? 1 : 0;
     28}
    2029
    2130extern "C" {
    22         void __enter_monitor_desc(monitor_desc * this) {
     31        void __enter_monitor_desc(monitor_desc * this, monitor_desc * leader) {
    2332                lock( &this->lock );
    2433                thread_desc * thrd = this_thread();
    2534
     35                // //Update the stack owner
     36                // this->stack_owner = leader;
     37
     38                LIB_DEBUG_PRINT_SAFE("Entering %p (o: %p, r: %i)\n", this, this->owner, this->recursion);
     39
    2640                if( !this->owner ) {
    2741                        //No one has the monitor, just take it
    28                         this->owner = thrd;
    29                         this->recursion = 1;
     42                        set_owner( this, thrd );
    3043                }
    3144                else if( this->owner == thrd) {
     
    4457
    4558                unlock( &this->lock );
    46         }
    47 
    48         void __leave_monitor_desc(monitor_desc * this) {
     59                return;
     60        }
     61
     62        // leave pseudo code :
     63        //      decrement level
     64        //      leve == 0 ?
     65        //              no : done
     66        //              yes :
     67        //                      signal stack empty ?
     68        //                              has leader :
     69        //                                      bulk acquiring means we don't own the signal stack
     70        //                                      ignore it but don't release the monitor
     71        //                              yes :
     72        //                                      next in entry queue is new owner
     73        //                              no :
     74        //                                      top of the signal stack is the owner
     75        //                                      context switch to him right away
     76        //
     77        void __leave_monitor_desc(monitor_desc * this, monitor_desc * leader) {
    4978                lock( &this->lock );
    5079
     80                LIB_DEBUG_PRINT_SAFE("Leaving %p (o: %p, r: %i)\n", this, this->owner, this->recursion);
     81
    5182                thread_desc * thrd = this_thread();
    52                 assert( thrd == this->owner );
     83                assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", this->owner, thrd, this->recursion );
    5384
    5485                //Leaving a recursion level, decrement the counter
    5586                this->recursion -= 1;
    5687
    57                 //If we left the last level of recursion it means we are changing who owns the monitor
     88                //If we haven't left the last level of recursion
     89                //it means we don't need to do anything
     90                if( this->recursion != 0) {
     91                        // this->stack_owner = leader;
     92                        unlock( &this->lock );
     93                        return;
     94                }
     95                       
     96                // //If we don't own the signal stack then just leave it to the owner
     97                // if( this->stack_owner ) {
     98                //      this->stack_owner = leader;
     99                //      unlock( &this->lock );
     100                //      return;
     101                // }
     102
     103                //We are the stack owner and have left the last recursion level.
     104                //We are in charge of passing the monitor
    58105                thread_desc * new_owner = 0;
    59                 if( this->recursion == 0) {
    60                         //Get the next thread in the list
    61                         new_owner = this->owner = pop_head( &this->entry_queue );
    62 
    63                         //We are passing the monitor to someone else, which means recursion level is not 0
    64                         this->recursion = new_owner ? 1 : 0;
    65                 }       
    66 
     106
     107                //Check the signaller stack
     108                new_owner = pop( &this->signal_stack );
     109                if( new_owner ) {
     110                        //The signaller stack is not empty,
     111                        //transfer control immediately
     112                        set_owner( this, new_owner );
     113                        // this->stack_owner = leader;
     114                        ScheduleInternal( &this->lock, new_owner );
     115                        return;
     116                }
     117               
     118                // No signaller thread
     119                // Get the next thread in the entry_queue
     120                new_owner = pop_head( &this->entry_queue );
     121                set_owner( this, new_owner );
     122
     123                // //Update the stack owner
     124                // this->stack_owner = leader;
     125
     126                //We can now let other threads in safely
    67127                unlock( &this->lock );
    68128
    69                 //If we have a new owner, we need to wake-up the thread
    70                 if( new_owner ) {
    71                         ScheduleThread( new_owner );
    72                 }
    73         }
    74 }
    75 
    76 void enter(monitor_desc ** monitors, int count) {
    77         for(int i = 0; i < count; i++) {
    78                 __enter_monitor_desc( monitors[i] );
    79         }
    80 }
    81 
    82 void leave(monitor_desc ** monitors, int count) {
    83         for(int i = count - 1; i >= 0; i--) {
    84                 __leave_monitor_desc( monitors[i] );
    85         }
    86 }
     129                //We need to wake-up the thread
     130                ScheduleThread( new_owner );
     131        }
     132}
     133
     134static inline void enter(monitor_desc ** monitors, int count) {
     135        __enter_monitor_desc( monitors[0], NULL );
     136        for(int i = 1; i < count; i++) {
     137                __enter_monitor_desc( monitors[i], monitors[0] );
     138        }
     139}
     140
     141static inline void leave(monitor_desc ** monitors, int count) {
     142        __leave_monitor_desc( monitors[0], NULL );
     143        for(int i = count - 1; i >= 1; i--) {
     144                __leave_monitor_desc( monitors[i], monitors[0] );
     145        }
     146}
     147
     148void ?{}( monitor_guard_t * this, monitor_desc ** m, int count ) {
     149        this->m = m;
     150        this->count = count;
     151        qsort(this->m, count);
     152        enter( this->m, this->count );
     153
     154        this->prev_mntrs = this_thread()->current_monitors;
     155        this->prev_count = this_thread()->current_monitor_count;
     156
     157        this_thread()->current_monitors      = m;
     158        this_thread()->current_monitor_count = count;
     159}
     160
     161void ^?{}( monitor_guard_t * this ) {
     162        leave( this->m, this->count );
     163
     164        this_thread()->current_monitors      = this->prev_mntrs;
     165        this_thread()->current_monitor_count = this->prev_count;
     166}
     167
     168//-----------------------------------------------------------------------------
     169// Internal scheduling
     170void wait( condition * this ) {
     171        assertf(false, "NO SUPPORTED");
     172        // LIB_DEBUG_FPRINTF("Waiting\n");
     173        thread_desc * this_thrd = this_thread();
     174
     175        if( !this->monitors ) {
     176                this->monitors = this_thrd->current_monitors;
     177                this->monitor_count = this_thrd->current_monitor_count;
     178        }
     179
     180        unsigned short count = this->monitor_count;
     181
     182        //Check that everything is as expected
     183        assert( this->monitors != NULL );
     184        assert( this->monitor_count != 0 );
     185
     186        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
     187        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
     188
     189        // LIB_DEBUG_FPRINTF("Getting ready to wait\n");
     190
     191        //Loop on all the monitors and release the owner
     192        for( unsigned int i = 0; i < count; i++ ) {
     193                monitor_desc * cur = this->monitors[i];
     194
     195                assert( cur );
     196
     197                // LIB_DEBUG_FPRINTF("cur %p lock %p\n", cur, &cur->lock);
     198
     199                //Store the locks for later
     200                locks[i] = &cur->lock;
     201
     202                //Protect the monitors
     203                lock( locks[i] );
     204                {               
     205                        //Save the recursion levels
     206                        recursions[i] = cur->recursion;
     207
     208                        //Release the owner
     209                        cur->recursion = 0;
     210                        cur->owner = NULL;
     211                }
     212                //Release the monitor
     213                unlock( locks[i] );
     214        }
     215
     216        // LIB_DEBUG_FPRINTF("Waiting now\n");
     217
     218        //Everything is ready to go to sleep
     219        ScheduleInternal( locks, count );
     220
     221
     222        //WE WOKE UP
     223
     224
     225        //We are back, restore the owners and recursions
     226        for( unsigned int i = 0; i < count; i++ ) {
     227                monitor_desc * cur = this->monitors[i];
     228
     229                //Protect the monitors
     230                lock( locks[i] );
     231                {
     232                        //Release the owner
     233                        cur->owner = this_thrd;
     234                        cur->recursion = recursions[i];
     235                }
     236                //Release the monitor
     237                unlock( locks[i] );
     238        }
     239}
     240
     241static void __signal_internal( condition * this ) {
     242        assertf(false, "NO SUPPORTED");
     243        if( !this->blocked.head ) return;
     244
     245        //Check that everything is as expected
     246        assert( this->monitors );
     247        assert( this->monitor_count != 0 );
     248       
     249        LIB_DEBUG_DO(
     250                if ( this->monitors != this_thread()->current_monitors ) {
     251                        abortf( "Signal on condition %p made outside of the correct monitor(s)", this );
     252                } // if
     253        );
     254
     255        monitor_desc * owner = this->monitors[0];
     256        lock( &owner->lock );
     257        {
     258                thread_desc * unblock = pop_head( &this->blocked );
     259                push( &owner->signal_stack, unblock );
     260        }
     261        unlock( &owner->lock );
     262}
     263
     264void signal( condition * this ) {
     265        __signal_internal( this );
     266}
  • src/libcfa/concurrency/thread.c

    r5c3632f rb3d70eb  
    3939        this->mon.recursion = 1;
    4040        this->next = NULL;
     41
     42        this->current_monitors      = NULL;
     43        this->current_monitor_count = 0;
    4144}
    4245
  • src/main.cc

    r5c3632f rb3d70eb  
    304304                GenPoly::box( translationUnit );
    305305
    306                 // print tree right before code generation
    307                 if ( codegenp ) {
    308                         dump( translationUnit );
    309                         return 0;
    310                 } // if
    311 
    312306                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
    313307                        output = new ofstream( argv[ optind ] );
    314308                } // if
    315309
    316                 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp );
     310                CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true );
    317311
    318312                CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" );
     
    393387                        break;
    394388                  case CtorInitFix:
    395                   case 'c':
     389                  case 'c':                                                                             // print after constructors and destructors are replaced
    396390                        ctorinitp = true;
    397391                        break;
     
    450444                        validp = true;
    451445                        break;
    452                   case 'y':
     446                  case 'y':                                                                             // dump AST on error
    453447                        errorp = true;
    454448                        break;
    455                   case 'z':
     449                  case 'z':                                                                             // dump as codegen rather than AST
    456450                        codegenp = true;
    457                         case 'Z':
     451                        break;
     452                        case 'Z':                                                                       // prettyprint during codegen (i.e. print unmangled names, etc.)
    458453                        prettycodegenp = true;
    459454                        break;
     
    501496        } // if
    502497
    503         printAll( decls, out );
     498        // depending on commandline options, either generate code or dump the AST
     499        if ( codegenp ) {
     500                CodeGen::generate( decls, out, ! noprotop, prettycodegenp );
     501        } else {
     502                printAll( decls, out );
     503        }
    504504        deleteAll( translationUnit );
    505505} // dump
  • src/tests/.expect/memberCtors-ERR1.txt

    r5c3632f rb3d70eb  
    1 memberCtors.c:62 error: in void ?{}(struct B *b), field a2 used before being constructed
     1memberCtors.c:62 error: in void ?{}(B *b), field a2 used before being constructed
    22make: *** [memberCtors-ERR1] Error 1
Note: See TracChangeset for help on using the changeset viewer.