Changes in / [656ee4f:626da644]


Ignore:
Files:
6 added
11 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r656ee4f r626da644  
    1717#include "Concurrency/Keywords.h"
    1818
     19#include "InitTweak/InitTweak.h"
    1920#include "SymTab/AddVisit.h"
    2021#include "SynTree/Declaration.h"
    2122#include "SynTree/Expression.h"
    2223#include "SynTree/Initializer.h"
    23 #include "SynTree/Mutator.h"
    2424#include "SynTree/Statement.h"
    2525#include "SynTree/Type.h"
     
    3838        // Visitors declaration
    3939        //=============================================================================================
     40
     41        //-----------------------------------------------------------------------------
     42        //Handles sue type declarations :
     43        // sue MyType {                             struct MyType {
     44        //      int data;                                  int data;
     45        //      a_struct_t more_data;                      a_struct_t more_data;
     46        //                                =>             NewField_t newField;
     47        // };                                        };
     48        //                                           static inline NewField_t * getter_name( MyType * this ) { return &this->newField; }
     49        //
     50        class ConcurrentSueKeyword : public Visitor {
     51          protected:
     52            template< typename Visitor >
     53            friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     54          public:
     55
     56                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main ) :
     57                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ) {}
     58
     59                virtual ~ConcurrentSueKeyword() {}
     60
     61                using Visitor::visit;
     62                virtual void visit( StructDecl * decl ) override final;
     63
     64                void handle( StructDecl * );
     65                FunctionDecl * forwardDeclare( StructDecl * );
     66                ObjectDecl * addField( StructDecl * );
     67                void addRoutines( StructDecl *, ObjectDecl *, FunctionDecl * );
     68
     69                virtual bool is_target( StructDecl * decl ) = 0;
     70
     71          private:
     72                const std::string type_name;
     73                const std::string field_name;
     74                const std::string getter_name;
     75                const std::string context_error;
     76                bool needs_main;
     77
     78                std::list< Declaration * > declsToAdd, declsToAddAfter;
     79                StructDecl* type_decl = nullptr;
     80        };
     81
    4082
    4183        //-----------------------------------------------------------------------------
     
    4789        // };                                        };
    4890        //                                           static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; }
    49         //                                           void main( MyThread * this );
    5091        //
    51         class ThreadKeyword final : public Mutator {
     92        class ThreadKeyword final : public ConcurrentSueKeyword {
    5293          public:
    5394
    54                 static void implement( std::list< Declaration * > & translationUnit ) {}
     95                ThreadKeyword() : ConcurrentSueKeyword(
     96                        "thread_desc",
     97                        "__thrd",
     98                        "get_thread",
     99                        "thread keyword requires threads to be in scope, add #include <thread>",
     100                        true
     101                )
     102                {}
     103
     104                virtual ~ThreadKeyword() {}
     105
     106                virtual bool is_target( StructDecl * decl ) override final { return decl->is_thread(); }
     107
     108                static void implement( std::list< Declaration * > & translationUnit ) {
     109                        ThreadKeyword impl;
     110                        SymTab::acceptAndAdd( translationUnit, impl );
     111                }
    55112        };
    56113
     
    63120        // };                                        };
    64121        //                                           static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
    65         //                                           void main( MyCoroutine * this );
    66122        //
    67         class CoroutineKeyword final : public Visitor {
    68             template< typename Visitor >
    69             friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     123        class CoroutineKeyword final : public ConcurrentSueKeyword {
    70124          public:
    71125
    72                 using Visitor::visit;
    73                 virtual void visit( StructDecl * decl ) override final;
    74 
    75                 void handle( StructDecl * );
    76                 Declaration * addField( StructDecl * );
    77                 void addRoutines( StructDecl *, Declaration * );
     126                CoroutineKeyword() : ConcurrentSueKeyword(
     127                        "coroutine_desc",
     128                        "__cor",
     129                        "get_coroutine",
     130                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine>",
     131                        true
     132                )
     133                {}
     134
     135                virtual ~CoroutineKeyword() {}
     136
     137                virtual bool is_target( StructDecl * decl ) override final { return decl->is_coroutine(); }
    78138
    79139                static void implement( std::list< Declaration * > & translationUnit ) {
     
    81141                        SymTab::acceptAndAdd( translationUnit, impl );
    82142                }
    83 
    84           private:
    85                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    86                 StructDecl* coroutine_decl = nullptr;
    87143        };
    88144
     
    95151        // };                                        };
    96152        //                                           static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
    97         //                                           void main( MyMonitor * this );
    98153        //
    99         class MonitorKeyword final : public Mutator {
     154        class MonitorKeyword final : public ConcurrentSueKeyword {
    100155          public:
    101156
    102                 static void implement( std::list< Declaration * > & translationUnit ) {}
     157                MonitorKeyword() : ConcurrentSueKeyword(
     158                        "monitor_desc",
     159                        "__mon",
     160                        "get_monitor",
     161                        "monitor keyword requires monitors to be in scope, add #include <monitor>",
     162                        false
     163                )
     164                {}
     165
     166                virtual ~MonitorKeyword() {}
     167
     168                virtual bool is_target( StructDecl * decl ) override final { return decl->is_monitor(); }
     169
     170                static void implement( std::list< Declaration * > & translationUnit ) {
     171                        MonitorKeyword impl;
     172                        SymTab::acceptAndAdd( translationUnit, impl );
     173                }
    103174        };
    104175
     
    132203        };
    133204
     205        //-----------------------------------------------------------------------------
     206        //Handles mutex routines definitions :
     207        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
     208        //                                                                       monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     209        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
     210        //    /*Some code*/                                       =>           /*Some code*/
     211        // }                                                               }
     212        //
     213        class ThreadStarter final : public Visitor {
     214          public:
     215
     216                using Visitor::visit;
     217                virtual void visit( FunctionDecl * decl ) override final;
     218
     219                void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
     220
     221                static void implement( std::list< Declaration * > & translationUnit ) {
     222                        ThreadStarter impl;
     223                        acceptAll( translationUnit, impl );
     224                }
     225        };
     226
    134227        //=============================================================================================
    135228        // General entry routine
     
    139232                CoroutineKeyword        ::implement( translationUnit );
    140233                MonitorKeyword  ::implement( translationUnit );
     234        }
     235
     236        void implementMutexFuncs( std::list< Declaration * > & translationUnit ) {
    141237                MutexKeyword    ::implement( translationUnit );
    142238        }
    143239
    144         //=============================================================================================
    145         // Coroutine keyword implementation
    146         //=============================================================================================
    147         void CoroutineKeyword::visit(StructDecl * decl) {
    148                 if( decl->get_name() == "coroutine_desc" ) {
    149                         assert( !coroutine_decl );
    150                         coroutine_decl = decl;
    151                 }
    152                 else if ( decl->is_coroutine() ) {
     240        void implementThreadStarter( std::list< Declaration * > & translationUnit ) {
     241                ThreadStarter   ::implement( translationUnit );
     242        }
     243
     244        //=============================================================================================
     245        // Generic keyword implementation
     246        //=============================================================================================
     247        void ConcurrentSueKeyword::visit(StructDecl * decl) {
     248                if( decl->get_name() == type_name ) {
     249                        assert( !type_decl );
     250                        type_decl = decl;
     251                }
     252                else if ( is_target(decl) ) {
    153253                        handle( decl );
    154254                }
     
    156256        }
    157257
    158         void CoroutineKeyword::handle( StructDecl * decl ) {
     258        void ConcurrentSueKeyword::handle( StructDecl * decl ) {
    159259                if( ! decl->has_body() ) return;
    160260
    161                 if( !coroutine_decl ) throw SemanticError( "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", decl );
    162 
    163                 Declaration * field = addField( decl );
    164                 addRoutines( decl, field );
    165         }
    166 
    167         Declaration * CoroutineKeyword::addField( StructDecl * decl ) {
    168                 Declaration * cor = new ObjectDecl(
    169                         "__cor",
     261                if( !type_decl ) throw SemanticError( context_error, decl );
     262
     263                FunctionDecl * func = forwardDeclare( decl );
     264                ObjectDecl * field = addField( decl );
     265                addRoutines( decl, field, func );
     266        }
     267
     268        FunctionDecl * ConcurrentSueKeyword::forwardDeclare( StructDecl * decl ) {
     269
     270                StructDecl * forward = decl->clone();
     271                forward->set_body( false );
     272                deleteAll( forward->get_members() );
     273                forward->get_members().clear();
     274
     275                FunctionType * get_type = new FunctionType( noQualifiers, false );
     276                ObjectDecl * this_decl = new ObjectDecl(
     277                        "this",
    170278                        noStorage,
    171279                        LinkageSpec::Cforall,
    172280                        nullptr,
    173                         new StructInstType(
     281                        new PointerType(
    174282                                noQualifiers,
    175                                 coroutine_decl
     283                                new StructInstType(
     284                                        noQualifiers,
     285                                        decl
     286                                )
    176287                        ),
    177288                        nullptr
    178289                );
    179290
    180                 decl->get_members().push_back( cor );
    181 
    182                 return cor;
    183         }
    184 
    185         void CoroutineKeyword::addRoutines( StructDecl * decl, Declaration * field ) {
    186                 FunctionType * type = new FunctionType( noQualifiers, false );
    187                 type->get_parameters().push_back(
    188                         new ObjectDecl(
    189                                 "this",
    190                                 noStorage,
    191                                 LinkageSpec::Cforall,
    192                                 nullptr,
    193                                 new PointerType(
    194                                         noQualifiers,
    195                                         new StructInstType(
    196                                                 noQualifiers,
    197                                                 decl
    198                                         )
    199                                 ),
    200                                 nullptr
    201                         )
    202                 );
    203                 type->get_returnVals().push_back(
     291                get_type->get_parameters().push_back( this_decl );
     292                get_type->get_returnVals().push_back(
    204293                        new ObjectDecl(
    205294                                "ret",
     
    211300                                        new StructInstType(
    212301                                                noQualifiers,
    213                                                 coroutine_decl
     302                                                type_decl
    214303                                        )
    215304                                ),
     
    218307                );
    219308
     309                FunctionDecl * get_decl = new FunctionDecl(
     310                        getter_name,
     311                        Type::Static,
     312                        LinkageSpec::Cforall,
     313                        get_type,
     314                        nullptr,
     315                        noAttributes,
     316                        Type::Inline
     317                );
     318
     319                FunctionDecl * main_decl = nullptr;
     320
     321                if( needs_main ) {
     322                        FunctionType * main_type = new FunctionType( noQualifiers, false );
     323                       
     324                        main_type->get_parameters().push_back( this_decl->clone() );
     325
     326                        main_decl = new FunctionDecl(
     327                                "main",
     328                                noStorage,
     329                                LinkageSpec::Cforall,
     330                                main_type,
     331                                nullptr
     332                        );
     333                }
     334
     335                declsToAdd.push_back( forward );
     336                if( needs_main ) declsToAdd.push_back( main_decl );
     337                declsToAdd.push_back( get_decl );
     338
     339                return get_decl;
     340        }
     341
     342        ObjectDecl * ConcurrentSueKeyword::addField( StructDecl * decl ) {
     343                ObjectDecl * field = new ObjectDecl(
     344                        field_name,
     345                        noStorage,
     346                        LinkageSpec::Cforall,
     347                        nullptr,
     348                        new StructInstType(
     349                                noQualifiers,
     350                                type_decl
     351                        ),
     352                        nullptr
     353                );
     354
     355                decl->get_members().push_back( field );
     356
     357                return field;
     358        }
     359
     360        void ConcurrentSueKeyword::addRoutines( StructDecl * decl, ObjectDecl * field, FunctionDecl * func ) {
    220361                CompoundStmt * statement = new CompoundStmt( noLabels );
    221362                statement->push_back(
     
    223364                                noLabels,
    224365                                new AddressExpr(
    225                                         new UntypedMemberExpr(
    226                                                 new NameExpr( "__cor" ),
    227                                                 new UntypedExpr(
    228                                                         new NameExpr( "*?" ),
    229                                                         { new NameExpr( "this" ) }
    230                                                 )
     366                                        new MemberExpr(
     367                                                field,
     368                                                UntypedExpr::createDeref( new VariableExpr( func->get_functionType()->get_parameters().front() ) )
    231369                                        )
    232370                                )
     
    234372                );
    235373
    236                 FunctionDecl * get_decl = new FunctionDecl(
    237                         "get_coroutine",
    238                         Type::Static,
    239                         LinkageSpec::Cforall,
    240                         type,
    241                         statement,
    242                         noAttributes,
    243                         Type::Inline
    244                 );
     374                FunctionDecl * get_decl = func->clone();
     375
     376                get_decl->set_statements( statement );
    245377
    246378                declsToAddAfter.push_back( get_decl );
    247379
    248                 get_decl->fixUniqueId();
    249         }
    250        
     380                // get_decl->fixUniqueId();
     381        }
    251382
    252383        //=============================================================================================
     
    368499                body->push_front( new DeclStmt( noLabels, monitors) );
    369500        }
     501
     502        //=============================================================================================
     503        // General entry routine
     504        //=============================================================================================
     505        void ThreadStarter::visit(FunctionDecl * decl) {
     506                if( ! InitTweak::isConstructor(decl->get_name()) ) return;
     507
     508                DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
     509                auto ptr = dynamic_cast< PointerType * >( param->get_type() );
     510                // if( ptr ) std::cerr << "FRED1" << std::endl;
     511                auto type  = dynamic_cast< StructInstType * >( ptr->get_base() );
     512                // if( type ) std::cerr << "FRED2" << std::endl;
     513                if( type && type->get_baseStruct()->is_thread() ) {
     514                        addStartStatement( decl, param );
     515                }
     516        }
     517
     518        void ThreadStarter::addStartStatement( FunctionDecl * decl, DeclarationWithType * param ) {
     519                CompoundStmt * stmt = decl->get_statements();
     520
     521                if( ! stmt ) return;
     522
     523                stmt->push_back(
     524                        new ExprStmt(
     525                                noLabels,
     526                                new UntypedExpr(
     527                                        new NameExpr( "__thrd_start" ),
     528                                        { new VariableExpr( param ) }
     529                                )
     530                        )
     531                );
     532        }
    370533};
  • src/Concurrency/Keywords.h

    r656ee4f r626da644  
    2424namespace Concurrency {
    2525        void applyKeywords( std::list< Declaration * > & translationUnit );
     26        void implementMutexFuncs( std::list< Declaration * > & translationUnit );
     27        void implementThreadStarter( std::list< Declaration * > & translationUnit );
    2628};
    2729
  • src/Parser/lex.ll

    r656ee4f r626da644  
    236236long                    { KEYWORD_RETURN(LONG); }
    237237lvalue                  { KEYWORD_RETURN(LVALUE); }                             // CFA
    238 _Monitor                { KEYWORD_RETURN(MONITOR); }                    // CFA
     238monitor         { KEYWORD_RETURN(MONITOR); }                    // CFA
    239239mutex                   { KEYWORD_RETURN(MUTEX); }                              // CFA
    240240_Noreturn               { KEYWORD_RETURN(NORETURN); }                   // C11
     
    256256struct                  { KEYWORD_RETURN(STRUCT); }
    257257switch                  { KEYWORD_RETURN(SWITCH); }
    258 _Thread                 { KEYWORD_RETURN(THREAD); }                             // C11
     258thread                  { KEYWORD_RETURN(THREAD); }                             // C11
    259259_Thread_local   { KEYWORD_RETURN(THREADLOCAL); }                // C11
    260260throw                   { KEYWORD_RETURN(THROW); }                              // CFA
  • src/SymTab/Autogen.cc

    r656ee4f r626da644  
    218218
    219219                /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
    220                 void gen( const FuncData & data ) {
     220                void gen( const FuncData & data, bool concurrent_type ) {
    221221                        if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
    222222                        FunctionType * ftype = data.genType( refType );
     223
     224                        if(concurrent_type && InitTweak::isDestructor( data.fname )) {
     225                                ftype->get_parameters().front()->get_type()->set_mutex( true );
     226                        }
     227
    223228                        cloneAll( typeParams, ftype->get_forall() );
    224229                        *out++ = genFunc( data.fname, ftype, functionNesting );
     
    403408                auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
    404409                for ( const FuncData & d : data ) {
    405                         generator.gen( d );
    406                 }
     410                        generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() );
     411                }
     412
    407413                // field ctors are only generated if default constructor and copy constructor are both generated
    408414                unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
  • src/SymTab/Validate.cc

    r656ee4f r626da644  
    4343#include "Common/utility.h"
    4444#include "Common/UniqueName.h"
     45#include "Concurrency/Keywords.h"
    4546#include "Validate.h"
    4647#include "SynTree/Visitor.h"
     
    225226                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    226227                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
     228                Concurrency::applyKeywords( translationUnit );
    227229                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     230                Concurrency::implementMutexFuncs( translationUnit );
     231                Concurrency::implementThreadStarter( translationUnit );
    228232                acceptAll( translationUnit, epc );
    229233                ReturnChecker::checkFunctionReturns( translationUnit );
  • src/libcfa/concurrency/thread

    r656ee4f r626da644  
    5656thread_desc * this_thread(void);
    5757
     58forall( dtype T | is_thread(T) )
     59void __thrd_start( T* this );
     60
    5861//-----------------------------------------------------------------------------
    5962// Ctors and dtors
  • src/libcfa/concurrency/thread.c

    r656ee4f r626da644  
    3131
    3232//-----------------------------------------------------------------------------
    33 // Forward declarations
    34 forall( dtype T | is_thread(T) )
    35 void start( T* this );
    36 
    37 //-----------------------------------------------------------------------------
    3833// Thread ctors and dtors
    3934
     
    5348void ?{}( scoped(T)* this ) {
    5449        (&this->handle){};
    55         start(&this->handle);
     50        __thrd_start(&this->handle);
    5651}
    5752
     
    5954void ?{}( scoped(T)* this, P params ) {
    6055        (&this->handle){ params };
    61         start(&this->handle);
     56        __thrd_start(&this->handle);
    6257}
    6358
     
    7065// Starting and stopping threads
    7166forall( dtype T | is_thread(T) )
    72 void start( T* this ) {
     67void __thrd_start( T* this ) {
    7368        coroutine_desc* thrd_c = get_coroutine(this);
    7469        thread_desc*  thrd_h = get_thread   (this);
  • src/main.cc

    r656ee4f r626da644  
    216216                } // if
    217217
     218                // OPTPRINT( "Concurrency" )
     219                // Concurrency::applyKeywords( translationUnit );
     220
    218221                // add the assignment statement after the initialization of a type parameter
    219222                OPTPRINT( "validate" )
     
    237240                OPTPRINT( "mutate" )
    238241                ControlStruct::mutate( translationUnit );
    239                 OPTPRINT( "Concurrency" )
    240                 Concurrency::applyKeywords( translationUnit );
    241242                OPTPRINT( "fixNames" )
    242243                CodeGen::fixNames( translationUnit );
  • src/tests/monitor.c

    r656ee4f r626da644  
    44#include <thread>
    55
    6 struct global_t {
     6monitor global_t {
    77        int value;
    8         monitor_desc m;
    98};
    109
    1110void ?{}(global_t * this) {
    1211        this->value = 0;
    13 }
    14 
    15 monitor_desc * get_monitor( global_t * this ) {
    16         return &this->m;
    1712}
    1813
     
    3126}
    3227
    33 struct MyThread { thread_desc __thrd; };
    34 
    35 DECL_THREAD(MyThread);
    36 
    37 void ?{}( MyThread * this ) {}
    38 void ^?{}( MyThread * mutex this ) {}
     28thread MyThread {};
    3929
    4030void main( MyThread* this ) {
     
    4535
    4636int main(int argc, char* argv[]) {
    47         assert( global.m.entry_queue.tail != NULL );
     37        assert( global.__mon.entry_queue.tail != NULL );
    4838        processor p;
    4939        {
    50                 scoped(MyThread) f[4];
     40                MyThread f[4];
    5141        }
    5242        sout | global.value | endl;
  • src/tests/multi-monitor.c

    r656ee4f r626da644  
    66static int global12, global23, global13;
    77
    8 struct monitor_t {
    9         monitor_desc m;
    10 };
    11 
    12 monitor_desc * get_monitor( monitor_t * this ) {
    13         return &this->m;
    14 }
     8monitor monitor_t {};
    159
    1610static monitor_t m1, m2, m3;
  • src/tests/thread.c

    r656ee4f r626da644  
    44#include <thread>
    55
    6 struct First { thread_desc __thrd; signal_once* lock; };
    7 struct Second { thread_desc __thrd; signal_once* lock; };
     6// thread First;
     7// void main(First* this);
    88
    9 DECL_THREAD(First);
    10 DECL_THREAD(Second);
     9// thread Second;
     10// void main(Second* this);
     11
     12thread First  { signal_once* lock; };
     13thread Second { signal_once* lock; };
    1114
    1215void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
    1316void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
    14 
    15 void ^?{}( First  * mutex this ) {}
    16 void ^?{}( Second * mutex this ) {}
    1717
    1818void main(First* this) {
     
    3939                processor p;
    4040                {
    41                         scoped(First)  f = { &lock };
    42                         scoped(Second) s = { &lock };
     41                        First  f = { &lock };
     42                        Second s = { &lock };
    4343                }
    4444        }
Note: See TracChangeset for help on using the changeset viewer.