Changes in / [11a2d9b:3096ec1]


Ignore:
Location:
src
Files:
2 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r11a2d9b r3096ec1  
    196196                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
    197197                void validate( DeclarationWithType * );
    198                 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    199198                void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    200199
     
    207206                StructDecl* monitor_decl = nullptr;
    208207                StructDecl* guard_decl = nullptr;
    209                 StructDecl* dtor_guard_decl = nullptr;
    210208
    211209                static std::unique_ptr< Type > generic_func;
     
    231229
    232230                void postvisit( FunctionDecl * decl );
    233                 void previsit ( StructDecl   * decl );
    234231
    235232                void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
     
    239236                        acceptAll( translationUnit, impl );
    240237                }
    241 
    242           private :
    243                 bool thread_ctor_seen = false;
    244                 StructDecl * thread_decl = nullptr;
    245238        };
    246239
     
    410403                if( mutexArgs.empty() ) return;
    411404
    412                 if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl );
    413 
    414                 bool isDtor = CodeGen::isDestructor( decl->name );
    415 
    416                 if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl );
    417 
    418405                for(auto arg : mutexArgs) {
    419406                        validate( arg );
     
    425412                if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    426413                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    427                 if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    428 
    429                 if( isDtor ) {
    430                         addDtorStatments( decl, body, mutexArgs );
    431                 }
    432                 else {
    433                         addStatments( decl, body, mutexArgs );
    434                 }
     414
     415                addStatments( decl, body, mutexArgs );
    435416        }
    436417
     
    444425                        assert( !guard_decl );
    445426                        guard_decl = decl;
    446                 }
    447                 else if( decl->name == "monitor_dtor_guard_t" ) {
    448                         assert( !dtor_guard_decl );
    449                         dtor_guard_decl = decl;
    450427                }
    451428        }
     
    480457                //Make sure that typed isn't mutex
    481458                if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
    482         }
    483 
    484         void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    485                 Type * arg_type = args.front()->get_type()->clone();
    486                 arg_type->set_mutex( false );
    487 
    488                 ObjectDecl * monitors = new ObjectDecl(
    489                         "__monitor",
    490                         noStorage,
    491                         LinkageSpec::Cforall,
    492                         nullptr,
    493                         new PointerType(
    494                                 noQualifiers,
    495                                 new StructInstType(
    496                                         noQualifiers,
    497                                         monitor_decl
    498                                 )
    499                         ),
    500                         new SingleInit( new UntypedExpr(
    501                                 new NameExpr( "get_monitor" ),
    502                                 {  new CastExpr( new VariableExpr( args.front() ), arg_type ) }
    503                         ))
    504                 );
    505 
    506                 assert(generic_func);
    507 
    508                 //in reverse order :
    509                 // monitor_guard_t __guard = { __monitors, #, func };
    510                 body->push_front(
    511                         new DeclStmt( noLabels, new ObjectDecl(
    512                                 "__guard",
    513                                 noStorage,
    514                                 LinkageSpec::Cforall,
    515                                 nullptr,
    516                                 new StructInstType(
    517                                         noQualifiers,
    518                                         dtor_guard_decl
    519                                 ),
    520                                 new ListInit(
    521                                         {
    522                                                 new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),
    523                                                 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
    524                                         },
    525                                         noDesignators,
    526                                         true
    527                                 )
    528                         ))
    529                 );
    530 
    531                 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
    532                 body->push_front( new DeclStmt( noLabels, monitors) );
    533459        }
    534460
     
    597523        // General entry routine
    598524        //=============================================================================================
    599         void ThreadStarter::previsit( StructDecl * decl ) {
    600                 if( decl->name == "thread_desc" && decl->body ) {
    601                         assert( !thread_decl );
    602                         thread_decl = decl;
    603                 }
    604         }
    605 
    606525        void ThreadStarter::postvisit(FunctionDecl * decl) {
    607526                if( ! CodeGen::isConstructor(decl->name) ) return;
    608 
    609                 Type * typeof_this = InitTweak::getTypeofThis(decl->type);
    610                 StructInstType * ctored_type = dynamic_cast< StructInstType * >( typeof_this );
    611                 if( ctored_type && ctored_type->baseStruct == thread_decl ) {
    612                         thread_ctor_seen = true;
    613                 }
    614527
    615528                DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
    616529                auto type  = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) );
    617530                if( type && type->get_baseStruct()->is_thread() ) {
    618                         if( !thread_decl || !thread_ctor_seen ) {
    619                                 throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");
    620                         }
    621 
    622531                        addStartStatement( decl, param );
    623532                }
  • src/InitTweak/InitTweak.cc

    r11a2d9b r3096ec1  
    270270        }
    271271
    272         Type * getTypeofThis( FunctionType * ftype ) {
    273                 assertf( ftype, "getTypeofThis: nullptr ftype" );
    274                 ObjectDecl * thisParam = getParamThis( ftype );
     272        Type * getThisType( FunctionType * ftype ) {
     273                assertf( ftype, "getThisType: nullptr ftype" );
     274                ObjectDecl * thisParam = getThisParam( ftype );
    275275                ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( thisParam->type );
    276276                return refType->base;
    277277        }
    278278
    279         ObjectDecl * getParamThis( FunctionType * ftype ) {
    280                 assertf( ftype, "getParamThis: nullptr ftype" );
     279        ObjectDecl * getThisParam( FunctionType * ftype ) {
     280                assertf( ftype, "getThisParam: nullptr ftype" );
    281281                auto & params = ftype->parameters;
    282                 assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( ftype ).c_str() );
     282                assertf( ! params.empty(), "getThisParam: ftype with 0 parameters: %s", toString( ftype ).c_str() );
    283283                return strict_dynamic_cast< ObjectDecl * >( params.front() );
    284284        }
  • src/InitTweak/InitTweak.h

    r11a2d9b r3096ec1  
    3131
    3232        /// returns the base type of the first parameter to a constructor/destructor/assignment function
    33         Type * getTypeofThis( FunctionType * ftype );
     33        Type * getThisType( FunctionType * ftype );
    3434
    3535        /// returns the first parameter of a constructor/destructor/assignment function
    36         ObjectDecl * getParamThis( FunctionType * ftype );
     36        ObjectDecl * getThisParam( FunctionType * ftype );
    3737
    3838        /// transform Initializer into an argument list that can be passed to a call expression
  • src/Parser/ExpressionNode.cc

    r11a2d9b r3096ec1  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Sep 27 22:51:55 2017
    13 // Update Count     : 781
     12// Last Modified On : Tue Sep 26 11:23:36 2017
     13// Update Count     : 780
    1414//
    1515
     
    207207
    208208        assert( 0 <= size && size < 6 );
    209         // Constant type is correct for overload resolving.
    210209        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    211         if ( Unsigned && size < 2 ) {                                           // hh or h, less than int ?
     210        if ( size < 2 ) {                                                                       // hh or h, less than int ?
    212211                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    213212                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
  • src/libcfa/concurrency/invoke.h

    r11a2d9b r3096ec1  
    9696            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    9797            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
    98             struct __waitfor_mask_t mask;             // mask used to know if some thread is waiting for something while holding the monitor
    99             struct __condition_node_t * dtor_node;    // node used to signal the dtor in a waitfor dtor
     98            struct __waitfor_mask_t mask;               // mask used to know if some thread is waiting for something while holding the monitor
    10099      };
    101100
  • src/libcfa/concurrency/monitor

    r11a2d9b r3096ec1  
    2929static inline void ?{}(monitor_desc & this) {
    3030        (this.lock){};
     31        this.owner = NULL;
    3132        (this.entry_queue){};
    3233        (this.signal_stack){};
    33         this.owner         = NULL;
    34         this.recursion     = 0;
     34        this.recursion = 0;
    3535        this.mask.accepted = NULL;
    3636        this.mask.clauses  = NULL;
    3737        this.mask.size     = 0;
    38         this.dtor_node     = NULL;
    3938}
    40 
    41 // static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
    42 //      return ((intptr_t)lhs) < ((intptr_t)rhs);
    43 // }
    4439
    4540struct monitor_guard_t {
     
    5146};
    5247
     48static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
     49        return ((intptr_t)lhs) < ((intptr_t)rhs);
     50}
     51
    5352void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
    5453void ^?{}( monitor_guard_t & this );
    55 
    56 
    57 struct monitor_dtor_guard_t {
    58         monitor_desc * m;
    59         monitor_desc ** prev_mntrs;
    60         unsigned short  prev_count;
    61         fptr_t          prev_func;
    62 };
    63 
    64 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, void (*func)() );
    65 void ^?{}( monitor_dtor_guard_t & this );
    6654
    6755//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor.c

    r11a2d9b r3096ec1  
    9494                }
    9595                else if( this->owner == thrd) {
    96                         // We already have the monitor, just note how many times we took it
     96                        // We already have the monitor, just not how many times we took it
    9797                        verify( this->recursion > 0 );
    9898                        this->recursion += 1;
     
    127127                unlock( &this->lock );
    128128                return;
    129         }
    130 
    131         static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    132                 // Lock the monitor spinlock, lock_yield to reduce contention
    133                 lock_yield( &this->lock DEBUG_CTX2 );
    134                 thread_desc * thrd = this_thread;
    135 
    136                 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
    137 
    138 
    139                 if( !this->owner ) {
    140                         LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this);
    141 
    142                         // No one has the monitor, just take it
    143                         set_owner( this, thrd );
    144 
    145                         unlock( &this->lock );
    146                         return;
    147                 }
    148                 else if( this->owner == thrd) {
    149                         // We already have the monitor... but where about to destroy it so the nesting will fail
    150                         // Abort!
    151                         abortf("Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.");
    152                 }
    153 
    154                 int count = 1;
    155                 monitor_desc ** monitors = &this;
    156                 __monitor_group_t group = { &this, 1, func };
    157                 if( is_accepted( this, group) ) {
    158                         LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts dtor, block and signal it \n");
    159 
    160                         // Wake the thread that is waiting for this
    161                         __condition_criterion_t * urgent = pop( &this->signal_stack );
    162                         verify( urgent );
    163 
    164                         // Reset mask
    165                         reset_mask( this );
    166 
    167                         // Create the node specific to this wait operation
    168                         wait_ctx_primed( this_thread, 0 )
    169 
    170                         // Some one else has the monitor, wait for him to finish and then run
    171                         BlockInternal( &this->lock, urgent->owner->waiting_thread );
    172 
    173                         // Some one was waiting for us, enter
    174                         set_owner( this, thrd );
    175                 }
    176                 else {
    177                         LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
    178 
    179                         wait_ctx( this_thread, 0 )
    180                         this->dtor_node = &waiter;
    181 
    182                         // Some one else has the monitor, wait in line for it
    183                         append( &this->entry_queue, thrd );
    184                         BlockInternal( &this->lock );
    185 
    186                         // BlockInternal will unlock spinlock, no need to unlock ourselves
    187                         return;
    188                 }
    189 
    190                 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this);
    191 
    192129        }
    193130
     
    221158        }
    222159
    223         // Leave single monitor for the last time
    224         void __leave_dtor_monitor_desc( monitor_desc * this ) {
    225                 LIB_DEBUG_DO(
    226                         if( this_thread != this->owner ) {
    227                                 abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
    228                         }
    229                         if( this->recursion != 1 ) {
    230                                 abortf("Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
    231                         }
    232                 )
    233         }
    234 
    235160        // Leave the thread monitor
    236161        // last routine called by a thread.
     
    285210// Ctor for monitor guard
    286211// Sorts monitors before entering
    287 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
     212void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
    288213        // Store current array
    289214        this.m = m;
     
    321246
    322247        // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");
    323 
    324         // Restore thread context
    325         this_thread->monitors.list = this.prev_mntrs;
    326         this_thread->monitors.size = this.prev_count;
    327         this_thread->monitors.func = this.prev_func;
    328 }
    329 
    330 
    331 // Ctor for monitor guard
    332 // Sorts monitors before entering
    333 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) {
    334         // Store current array
    335         this.m = *m;
    336 
    337         // Save previous thread context
    338         this.prev_mntrs = this_thread->monitors.list;
    339         this.prev_count = this_thread->monitors.size;
    340         this.prev_func  = this_thread->monitors.func;
    341 
    342         // Update thread context (needed for conditions)
    343         this_thread->monitors.list = m;
    344         this_thread->monitors.size = 1;
    345         this_thread->monitors.func = func;
    346 
    347         __enter_monitor_dtor( this.m, func );
    348 }
    349 
    350 
    351 // Dtor for monitor guard
    352 void ^?{}( monitor_dtor_guard_t & this ) {
    353         // Leave the monitors in order
    354         __leave_dtor_monitor_desc( this.m );
    355248
    356249        // Restore thread context
     
    555448                        *mask.accepted = index;
    556449                        if( mask.clauses[index].is_dtor ) {
    557                                 LIB_DEBUG_PRINT_SAFE("Kernel : dtor already there\n");
    558                                 verifyf( mask.clauses[index].size == 1        , "ERROR: Accepted dtor has more than 1 mutex parameter." );
    559 
    560                                 monitor_desc * mon2dtor = mask.clauses[index].list[0];
    561                                 verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." );
    562 
    563                                 __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
    564                                 push( &mon2dtor->signal_stack, dtor_crit );
    565 
    566                                 unlock_all( locks, count );
     450                                #warning case not implemented
    567451                        }
    568452                        else {
  • src/tests/.expect/64/literals.txt

    r11a2d9b r3096ec1  
    12521252    ((void)(-((long double )0x.0123456789p09)));
    12531253    ((void)__f__F_c__1('a'));
    1254     ((void)__f__F_Sc__1(20));
     1254    ((void)__f__F_Sc__1(((signed char )20)));
    12551255    ((void)__f__F_Uc__1(((unsigned char )21u)));
    1256     ((void)__f__F_s__1(22));
     1256    ((void)__f__F_s__1(((signed short int )22)));
    12571257    ((void)__f__F_Us__1(((unsigned short int )23u)));
    12581258    ((void)__f__F_Ul__1(((unsigned long int )24)));
  • src/tests/Makefile.am

    r11a2d9b r3096ec1  
    2222concurrent = yes
    2323quick_test += coroutine thread monitor
    24 concurrent_test =        \
    25         coroutine          \
    26         thread             \
    27         monitor            \
    28         multi-monitor      \
    29         preempt            \
    30         sched-int-block    \
    31         sched-int-disjoint \
    32         sched-int-wait     \
    33         sched-ext-barge    \
    34         sched-ext-dtor     \
    35         sched-ext-else     \
    36         sched-ext-parse    \
    37         sched-ext-recurse  \
    38         sched-ext-statment \
    39         sched-ext-when
    40 
     24concurrent_test = coroutine thread monitor multi-monitor sched-int-block sched-int-disjoint sched-int-wait sched-ext-barge sched-ext-else sched-ext-parse sched-ext-statment preempt
    4125else
    4226concurrent=no
  • src/tests/Makefile.in

    r11a2d9b r3096ec1  
    320320@BUILD_CONCURRENCY_TRUE@concurrent = yes
    321321@BUILD_CONCURRENCY_FALSE@concurrent_test =
    322 @BUILD_CONCURRENCY_TRUE@concurrent_test = \
    323 @BUILD_CONCURRENCY_TRUE@        coroutine          \
    324 @BUILD_CONCURRENCY_TRUE@        thread             \
    325 @BUILD_CONCURRENCY_TRUE@        monitor            \
    326 @BUILD_CONCURRENCY_TRUE@        multi-monitor      \
    327 @BUILD_CONCURRENCY_TRUE@        preempt            \
    328 @BUILD_CONCURRENCY_TRUE@        sched-int-block    \
    329 @BUILD_CONCURRENCY_TRUE@        sched-int-disjoint \
    330 @BUILD_CONCURRENCY_TRUE@        sched-int-wait     \
    331 @BUILD_CONCURRENCY_TRUE@        sched-ext-barge    \
    332 @BUILD_CONCURRENCY_TRUE@        sched-ext-dtor     \
    333 @BUILD_CONCURRENCY_TRUE@        sched-ext-else     \
    334 @BUILD_CONCURRENCY_TRUE@        sched-ext-parse    \
    335 @BUILD_CONCURRENCY_TRUE@        sched-ext-recurse  \
    336 @BUILD_CONCURRENCY_TRUE@        sched-ext-statment \
    337 @BUILD_CONCURRENCY_TRUE@        sched-ext-when
    338 
     322@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-block sched-int-disjoint sched-int-wait sched-ext-barge sched-ext-else sched-ext-parse sched-ext-statment preempt
    339323
    340324# applies to both programs
  • src/tests/coroutine.c

    r11a2d9b r3096ec1  
    1010// Created On       : Thu Jun  8 07:29:37 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep 17 21:38:15 2017
    13 // Update Count     : 7
     12// Last Modified On : Thu Jun  8 07:37:12 2017
     13// Update Count     : 5
    1414//
    1515
     
    1818
    1919coroutine Fibonacci {
    20         int fn;                                                                                         // used for communication
     20        int fn;                                         // used for communication
    2121};
    2222
     
    2626
    2727void main( Fibonacci & this ) {
    28         int fn1, fn2;                                                                           // retained between resumes
    29         this.fn = 0;                                                                            // case 0
     28        int fn1, fn2;                                   // retained between resumes
     29        this.fn = 0;                                    // case 0
    3030        fn1 = this.fn;
    31         suspend();                                                                                      // restart last resume
     31        suspend();                                              // return to last resume
    3232
    33         this.fn = 1;                                                                            // case 1
    34         fn2 = fn1;  fn1 = this.fn;
    35         suspend();                                                                                      // restart last resume
     33        this.fn = 1;                                    // case 1
     34        fn2 = fn1;
     35        fn1 = this.fn;
     36        suspend();                                              // return to last resume
    3637
    37         for ( ;; ) {                                                                            // general case
     38        for ( ;; ) {                                    // general case
    3839                this.fn = fn1 + fn2;
    39                 fn2 = fn1;  fn1 = this.fn;
    40                 suspend();                                                                              // restart last resume
     40                fn2 = fn1;
     41                fn1 = this.fn;
     42                suspend();                                      // return to last resume
    4143        } // for
    4244}
    4345
    4446int next( Fibonacci & this ) {
    45         resume( this );                                                                         // restart last suspend
     47        resume( this );                                 // transfer to last suspend
    4648        return this.fn;
    4749}
     
    5052        Fibonacci f1, f2;
    5153        for ( int i = 1; i <= 10; i += 1 ) {
    52                 sout | next( f1 ) | next( f2 ) | endl;
     54                sout | next( f1 ) | ' ' | next( f2 ) | endl;
    5355        } // for
    5456}
  • src/tests/gmp.c

    r11a2d9b r3096ec1  
    1010// Created On       : Tue Apr 19 08:55:51 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Sep 28 18:33:51 2017
    13 // Update Count     : 555
     12// Last Modified On : Mon Sep  4 09:51:18 2017
     13// Update Count     : 550
    1414//
    1515
     
    9797
    9898        sout | "Factorial Numbers" | endl;
    99         Int fact = 1;                                                                           // 1st case
     99        Int fact;
     100        fact = 1;                                                                                       // 1st case
    100101        sout | (int)0 | fact | endl;
    101102        for ( unsigned int i = 1; i <= 40; i += 1 ) {
Note: See TracChangeset for help on using the changeset viewer.