Changes in / [b3d70eba:5c3632f]


Ignore:
Files:
1 deleted
16 edited

Legend:

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

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

    rb3d70eba r5c3632f  
    8989        }
    9090
    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 ) {}
     91        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ) {}
    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, genC );
     138                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty );
    139139
    140140                asmName( functionDecl );
     
    147147
    148148        void CodeGenerator::visit( ObjectDecl * objectDecl ) {
    149                 if (objectDecl->get_name().empty() && genC ) {
    150                         // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     149                if (objectDecl->get_name().empty()) {
    151150                        static UniqueName name = { "__anonymous_object" };
    152151                        objectDecl->set_name( name.newName() );
     
    157156
    158157                handleStorageClass( objectDecl );
    159                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
     158                output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty );
    160159
    161160                asmName( objectDecl );
     
    172171        }
    173172
    174         void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
     173        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) {
    175174                genAttributes( aggDecl->get_attributes() );
    176175
    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;
    185176                if ( aggDecl->get_name() != "" )
    186177                        output << aggDecl->get_name();
    187178
     179                // std::list< Declaration * > & memb = aggDecl->get_members();
     180                // if ( ! memb.empty() ) {
    188181                if ( aggDecl->has_body() ) {
    189182                        std::list< Declaration * > & memb = aggDecl->get_members();
     
    205198        void CodeGenerator::visit( StructDecl * structDecl ) {
    206199                extension( structDecl );
    207                 handleAggregate( structDecl, "struct " );
     200                output << "struct ";
     201                handleAggregate( structDecl );
    208202        }
    209203
    210204        void CodeGenerator::visit( UnionDecl * unionDecl ) {
    211205                extension( unionDecl );
    212                 handleAggregate( unionDecl, "union " );
     206                output << "union ";
     207                handleAggregate( unionDecl );
    213208        }
    214209
     
    247242
    248243        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
    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;
     244                assert( false && "Typedefs are removed and substituted in earlier passes." );
     245                //output << "typedef ";
     246                //output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty );
    252247        }
    253248
    254249        void CodeGenerator::visit( TypeDecl * typeDecl ) {
    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                 }
     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
    271257        }
    272258
     
    307293
    308294        void CodeGenerator::visit( ConstructorInit * init ){
    309                 assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    310                 // xxx - generate something reasonable for constructor/destructor pairs
    311                 output << "<ctorinit>";
     295                assertf( false, "ConstructorInit nodes should not make it to CodeGen." );
    312296        }
    313297
     
    563547                        // at least one result type of cast, but not an lvalue
    564548                        output << "(";
    565                         output << genType( castExpr->get_result(), "", pretty, genC );
     549                        output << genType( castExpr->get_result(), "", pretty );
    566550                        output << ")";
    567551                } else {
     
    574558
    575559        void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
    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 );
     560                assert( false );
    581561        }
    582562
     
    607587                output << "sizeof(";
    608588                if ( sizeofExpr->get_isType() ) {
    609                         output << genType( sizeofExpr->get_type(), "", pretty, genC );
     589                        output << genType( sizeofExpr->get_type(), "", pretty );
    610590                } else {
    611591                        sizeofExpr->get_expr()->accept( *this );
     
    619599                output << "__alignof__(";
    620600                if ( alignofExpr->get_isType() ) {
    621                         output << genType( alignofExpr->get_type(), "", pretty, genC );
     601                        output << genType( alignofExpr->get_type(), "", pretty );
    622602                } else {
    623603                        alignofExpr->get_expr()->accept( *this );
     
    627607
    628608        void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
    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 << ")";
     609                assert( false && "UntypedOffsetofExpr should not reach code generation." );
    634610        }
    635611
     
    637613                // use GCC builtin
    638614                output << "__builtin_offsetof(";
    639                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     615                output << genType( offsetofExpr->get_type(), "", pretty );
    640616                output << ", " << mangleName( offsetofExpr->get_member() );
    641617                output << ")";
     
    643619
    644620        void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
    645                 assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    646                 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
     621                assert( false && "OffsetPackExpr should not reach code generation." );
    647622        }
    648623
     
    680655        }
    681656
    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         }
     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 ) {}
    700662
    701663        void CodeGenerator::visit( AsmExpr * asmExpr ) {
     
    713675        void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
    714676                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    715                 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
     677                output << "(" << genType( compLitExpr->get_result(), "", pretty ) << ")";
    716678                compLitExpr->get_initializer()->accept( *this );
    717679        }
  • src/CodeGen/CodeGenerator.h

    rb3d70eba r5c3632f  
    3030                static int tabsize;
    3131
    32                 CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false );
     32                CodeGenerator( std::ostream &os, bool pretty = 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
    124123
    125124                void printDesignators( std::list< Expression * > & );
    126125                void handleStorageClass( DeclarationWithType *decl );
    127                 void handleAggregate( AggregateDecl *aggDecl, const std::string & kind );
     126                void handleAggregate( AggregateDecl *aggDecl );
    128127                void handleTypedef( NamedTypeDecl *namedType );
    129128                std::string mangleName( DeclarationWithType * decl );
  • src/CodeGen/GenType.cc

    rb3d70eba r5c3632f  
    2828        class GenType : public Visitor {
    2929          public:
    30                 GenType( const std::string &typeString, bool pretty = false, bool genC = false );
     30                GenType( const std::string &typeString, bool pretty = 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 );
    5150                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    5251
    5352                std::string typeString;
    5453                bool pretty = false; // pretty print
    55                 bool genC = false;   // generating C code?
    5654        };
    5755
    58         std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC ) {
    59                 GenType gt( baseString, pretty, genC );
     56        std::string genType( Type *type, const std::string &baseString, bool pretty ) {
     57                GenType gt( baseString, pretty );
    6058                std::ostringstream os;
    6159
    6260                if ( ! type->get_attributes().empty() ) {
    63                         CodeGenerator cg( os, pretty, genC );
     61                        CodeGenerator cg( os, pretty );
    6462                        cg.genAttributes( type->get_attributes() );
    6563                } // if
     
    7068
    7169  std::string genPrettyType( Type * type, const std::string & baseString ) {
    72         return genType( type, baseString, true, false );
     70        return genType( type, baseString, true );
    7371  }
    7472
    75         GenType::GenType( const std::string &typeString, bool pretty, bool genC ) : typeString( typeString ), pretty( pretty ), genC( genC ) {}
     73        GenType::GenType( const std::string &typeString, bool pretty ) : typeString( typeString ), pretty( pretty ) {}
    7674
    7775        void GenType::visit( VoidType *voidType ) {
     
    114112                } // if
    115113                if ( dimension != 0 ) {
    116                         CodeGenerator cg( os, pretty, genC );
     114                        CodeGenerator cg( os, pretty );
    117115                        dimension->accept( cg );
    118116                } else if ( isVarLen ) {
     
    168166                        } // if
    169167                } else {
    170                         CodeGenerator cg( os, pretty, genC );
     168                        CodeGenerator cg( os, pretty );
    171169                        os << "(" ;
    172170
     
    186184                        funcType->get_returnVals().front()->get_type()->accept( *this );
    187185                } // 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 "";
    211186        }
    212187
    213188        void GenType::visit( StructInstType *structInst )  {
    214                 typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString;
    215                 if ( genC ) typeString = "struct " + typeString;
     189                typeString = "struct " + structInst->get_name() + " " + typeString;
    216190                handleQualifiers( structInst );
    217191        }
    218192
    219193        void GenType::visit( UnionInstType *unionInst ) {
    220                 typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString;
    221                 if ( genC ) typeString = "union " + typeString;
     194                typeString = "union " + unionInst->get_name() + " " + typeString;
    222195                handleQualifiers( unionInst );
    223196        }
    224197
    225198        void GenType::visit( EnumInstType *enumInst ) {
    226                 typeString = enumInst->get_name() + " " + typeString;
    227                 if ( genC ) typeString = "enum " + typeString;
     199                typeString = "enum " + enumInst->get_name() + " " + typeString;
    228200                handleQualifiers( enumInst );
    229201        }
     
    235207
    236208        void GenType::visit( TupleType * tupleType ) {
    237                 assertf( ! genC, "Tuple types should not reach code generation." );
     209                assertf( pretty, "Tuple types should not make it to Code Gen." );
    238210                Visitor::visit( tupleType );
    239211                unsigned int i = 0;
     
    242214                for ( Type * t : *tupleType ) {
    243215                        i++;
    244                         os << genType( t, "", pretty, genC ) << (i == tupleType->size() ? "" : ", ");
     216                        os << genType( t, "", pretty ) << (i == tupleType->size() ? "" : ", ");
    245217                }
    246218                os << "]";
  • src/CodeGen/GenType.h

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

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

    rb3d70eba r5c3632f  
    2323
    2424namespace CodeGen {
    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 );
     25        /// Generates code
     26        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty );
    2727} // namespace CodeGen
    2828
  • src/SynTree/Declaration.h

    rb3d70eba r5c3632f  
    167167        std::list< DeclarationWithType* >& get_assertions() { return assertions; }
    168168
     169        virtual NamedTypeDecl *clone() const = 0;
     170        virtual void print( std::ostream &os, int indent = 0 ) const;
     171        virtual void printShort( std::ostream &os, int indent = 0 ) const;
     172  protected:
    169173        virtual std::string typeString() const = 0;
    170 
    171         virtual NamedTypeDecl *clone() const = 0;
    172         virtual void print( std::ostream &os, int indent = 0 ) const;
    173         virtual void printShort( std::ostream &os, int indent = 0 ) const;
    174   protected:
    175174  private:
    176175        Type *base;
     
    203202        TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
    204203
    205         virtual std::string typeString() const;
    206 
    207204        virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
    208205        virtual void accept( Visitor &v ) { v.visit( this ); }
    209206        virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    210207  private:
     208        virtual std::string typeString() const;
    211209        Kind kind;
    212210        bool sized;
     
    219217        TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    220218
    221         virtual std::string typeString() const;
    222 
    223219        virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); }
    224220        virtual void accept( Visitor &v ) { v.visit( this ); }
    225221        virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    226222  private:
     223        virtual std::string typeString() const;
    227224};
    228225
  • src/libcfa/concurrency/invoke.h

    rb3d70eba r5c3632f  
    3333      };
    3434
    35       struct __thread_queue_t {
     35      struct simple_thread_list {
    3636            struct thread_desc * head;
    3737            struct thread_desc ** tail;
    3838      };
    3939
    40       struct __thread_stack_t {
    41             struct thread_desc * top;
    42       };
    43 
    4440      #ifdef __CFORALL__
    4541      extern "Cforall" {
    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 * );
     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 * );
    5345
    5446            void ?{}(spinlock * this);
     
    5850
    5951      struct coStack_t {
    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
     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
    6759      };
    6860
     
    7062
    7163      struct coroutine_desc {
    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
     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
    7870      };
    7971
    8072      struct monitor_desc {
    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
     73            struct spinlock lock;
     74            struct thread_desc * owner;
     75            struct simple_thread_list entry_queue;
     76            unsigned int recursion;
    8777      };
    8878
    8979      struct thread_desc {
    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
     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
    9583      };
    9684
  • src/libcfa/concurrency/kernel

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

    rb3d70eba r5c3632f  
    299299// Scheduler routines
    300300void ScheduleThread( thread_desc * thrd ) {
    301         if( !thrd ) return;
    302 
    303301        assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
    304302       
     
    475473
    476474void ?{}( signal_once * this ) {
    477         this->cond = false;
     475        this->condition = false;
    478476}
    479477void ^?{}( signal_once * this ) {
     
    483481void wait( signal_once * this ) {
    484482        lock( &this->lock );
    485         if( !this->cond ) {
     483        if( !this->condition ) {
    486484                append( &this->blocked, this_thread() );
    487485                ScheduleInternal( &this->lock );
     
    494492        lock( &this->lock );
    495493        {
    496                 this->cond = true;
     494                this->condition = true;
    497495
    498496                thread_desc * it;
     
    506504//-----------------------------------------------------------------------------
    507505// Queues
    508 void ?{}( __thread_queue_t * this ) {
     506void ?{}( simple_thread_list * this ) {
    509507        this->head = NULL;
    510508        this->tail = &this->head;
    511509}
    512510
    513 void append( __thread_queue_t * this, thread_desc * t ) {
     511void append( simple_thread_list * this, thread_desc * t ) {
    514512        assert(this->tail != NULL);
    515513        *this->tail = t;
     
    517515}
    518516
    519 thread_desc * pop_head( __thread_queue_t * this ) {
     517thread_desc * pop_head( simple_thread_list * this ) {
    520518        thread_desc * head = this->head;
    521519        if( head ) {
     
    528526        return head;
    529527}
    530 
    531 void ?{}( __thread_stack_t * this ) {
    532         this->top = NULL;
    533 }
    534 
    535 void push( __thread_stack_t * this, thread_desc * t ) {
    536         assert(t->next != NULL);
    537         t->next = this->top;
    538         this->top = t;
    539 }
    540 
    541 thread_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 }
    549528// Local Variables: //
    550529// mode: c //
  • src/libcfa/concurrency/monitor

    rb3d70eba r5c3632f  
    1818#define MONITOR_H
    1919
    20 #include <stddef.h>
    21 
    2220#include "assert"
    2321#include "invoke.h"
     
    2523
    2624static inline void ?{}(monitor_desc * this) {
    27         this->owner = NULL;
    28       this->stack_owner = NULL;
     25        this->owner = 0;
    2926        this->recursion = 0;
    3027}
     28
     29//Array entering routine
     30void enter(monitor_desc **, int count);
     31void leave(monitor_desc **, int count);
    3132
    3233struct monitor_guard_t {
    3334        monitor_desc ** m;
    3435        int count;
    35       monitor_desc ** prev_mntrs;
    36       unsigned short  prev_count;
    3736};
    3837
     
    4140}
    4241
    43 void ?{}( monitor_guard_t * this, monitor_desc ** m, int count );
    44 void ^?{}( monitor_guard_t * this );
    45 
    46 //-----------------------------------------------------------------------------
    47 // Internal scheduling
    48 struct condition {
    49         __thread_queue_t blocked;
    50         monitor_desc ** monitors;
    51         unsigned short monitor_count;
    52 };
    53 
    54 static inline void ?{}( condition * this ) {
    55         this->monitors = NULL;
    56         this->monitor_count = 0;
     42static 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 );
    5747}
    5848
    59 void wait( condition * this );
    60 void signal( condition * this );
     49static inline void ^?{}( monitor_guard_t * this ) {
     50        leave( this->m, this->count );
     51}
     52
     53
    6154#endif //MONITOR_H
  • src/libcfa/concurrency/monitor.c

    rb3d70eba r5c3632f  
    1818
    1919#include "kernel_private.h"
    20 #include "libhdr.h"
    21 
    22 void 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 }
    2920
    3021extern "C" {
    31         void __enter_monitor_desc(monitor_desc * this, monitor_desc * leader) {
     22        void __enter_monitor_desc(monitor_desc * this) {
    3223                lock( &this->lock );
    3324                thread_desc * thrd = this_thread();
    3425
    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 
    4026                if( !this->owner ) {
    4127                        //No one has the monitor, just take it
    42                         set_owner( this, thrd );
     28                        this->owner = thrd;
     29                        this->recursion = 1;
    4330                }
    4431                else if( this->owner == thrd) {
     
    5744
    5845                unlock( &this->lock );
    59                 return;
    6046        }
    6147
    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) {
     48        void __leave_monitor_desc(monitor_desc * this) {
    7849                lock( &this->lock );
    7950
    80                 LIB_DEBUG_PRINT_SAFE("Leaving %p (o: %p, r: %i)\n", this, this->owner, this->recursion);
    81 
    8251                thread_desc * thrd = this_thread();
    83                 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", this->owner, thrd, this->recursion );
     52                assert( thrd == this->owner );
    8453
    8554                //Leaving a recursion level, decrement the counter
    8655                this->recursion -= 1;
    8756
    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                 // }
     57                //If we left the last level of recursion it means we are changing who owns the monitor
     58                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 );
    10262
    103                 //We are the stack owner and have left the last recursion level.
    104                 //We are in charge of passing the monitor
    105                 thread_desc * new_owner = 0;
     63                        //We are passing the monitor to someone else, which means recursion level is not 0
     64                        this->recursion = new_owner ? 1 : 0;
     65                }       
    10666
    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
    12767                unlock( &this->lock );
    12868
    129                 //We need to wake-up the thread
    130                 ScheduleThread( new_owner );
     69                //If we have a new owner, we need to wake-up the thread
     70                if( new_owner ) {
     71                        ScheduleThread( new_owner );
     72                }
    13173        }
    13274}
    13375
    134 static 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] );
     76void enter(monitor_desc ** monitors, int count) {
     77        for(int i = 0; i < count; i++) {
     78                __enter_monitor_desc( monitors[i] );
    13879        }
    13980}
    14081
    141 static 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] );
     82void leave(monitor_desc ** monitors, int count) {
     83        for(int i = count - 1; i >= 0; i--) {
     84                __leave_monitor_desc( monitors[i] );
    14585        }
    14686}
    147 
    148 void ?{}( 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 
    161 void ^?{}( 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
    170 void 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 
    241 static 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 
    264 void signal( condition * this ) {
    265         __signal_internal( this );
    266 }
  • src/libcfa/concurrency/thread.c

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

    rb3d70eba r5c3632f  
    304304                GenPoly::box( translationUnit );
    305305
     306                // print tree right before code generation
     307                if ( codegenp ) {
     308                        dump( translationUnit );
     309                        return 0;
     310                } // if
     311
    306312                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
    307313                        output = new ofstream( argv[ optind ] );
    308314                } // if
    309315
    310                 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true );
     316                CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp );
    311317
    312318                CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" );
     
    387393                        break;
    388394                  case CtorInitFix:
    389                   case 'c':                                                                             // print after constructors and destructors are replaced
     395                  case 'c':
    390396                        ctorinitp = true;
    391397                        break;
     
    444450                        validp = true;
    445451                        break;
    446                   case 'y':                                                                             // dump AST on error
     452                  case 'y':
    447453                        errorp = true;
    448454                        break;
    449                   case 'z':                                                                             // dump as codegen rather than AST
     455                  case 'z':
    450456                        codegenp = true;
    451                         break;
    452                         case 'Z':                                                                       // prettyprint during codegen (i.e. print unmangled names, etc.)
     457                        case 'Z':
    453458                        prettycodegenp = true;
    454459                        break;
     
    496501        } // if
    497502
    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         }
     503        printAll( decls, out );
    504504        deleteAll( translationUnit );
    505505} // dump
  • src/tests/.expect/memberCtors-ERR1.txt

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