Changeset 64aeca0


Ignore:
Timestamp:
Jan 10, 2021, 5:47:16 PM (8 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
2501ae5
Parents:
5a51798 (diff), 58fe85a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
36 added
9 edited

Legend:

Unmodified
Added
Removed
  • benchmark/creation/node_cor.js

    r5a51798 r64aeca0  
    66function * coroutine() { yield }
    77
    8 for ( var i = 0; i < times; i += 1 ) { // warm jit
     8for ( var i = 0; i < times; i += 1 ) { // warm JIT
    99        cor = coroutine()
    1010}
  • benchmark/ctxswitch/node_cor.js

    r5a51798 r64aeca0  
    1111cor = coroutine()
    1212
    13 for ( var i = 0; i < times; i += 1 ) { // warm git
     13for ( var i = 0; i < times; i += 1 ) { // warm JIT
    1414        cor.next();
    1515}
  • libcfa/src/Makefile.am

    r5a51798 r64aeca0  
    5858        concurrency/iofwd.hfa \
    5959        containers/list.hfa \
    60         containers/stackLockFree.hfa
     60        containers/stackLockFree.hfa \
     61        vec/vec.hfa \
     62        vec/vec2.hfa \
     63        vec/vec3.hfa \
     64        vec/vec4.hfa
    6165
    6266inst_headers_src = \
     
    9498        concurrency/clib/cfathread.h \
    9599        concurrency/invoke.h \
     100        concurrency/future.hfa \
    96101        concurrency/kernel/fwd.hfa
    97102
  • libcfa/src/bits/locks.hfa

    r5a51798 r64aeca0  
    283283                void ^?{}(future_t &) {}
    284284
     285                void reset(future_t & this) {
     286                        // needs to be in 0p or 1p
     287                        __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
     288                }
     289
    285290                // check if the future is available
    286291                bool available( future_t & this ) {
     
    340345
    341346                // Mark the future as abandoned, meaning it will be deleted by the server
    342                 void abandon( future_t & this ) {
     347                bool abandon( future_t & this ) {
     348                        /* paranoid */ verify( this.ptr != 3p );
     349
     350                        // Mark the future as abandonned
    343351                        struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST);
     352
     353                        // If the future isn't already fulfilled, let the server delete it
     354                        if( got == 0p ) return false;
    344355
    345356                        // got == 2p: the future is ready but the context hasn't fully been consumed
     
    347358                        if( got == 2p ) {
    348359                                while( this.ptr != 1p ) Pause();
    349                         }
    350                         return;
     360                                got = 1p;
     361                        }
     362
     363                        // The future is completed delete it now
     364                        /* paranoid */ verify( this.ptr != 1p );
     365                        free( &this );
     366                        return true;
    351367                }
    352368
  • libcfa/src/concurrency/monitor.hfa

    r5a51798 r64aeca0  
    132132
    133133              void wait        ( condition & this, uintptr_t user_info = 0 );
     134static inline bool is_empty    ( condition & this ) { return this.blocked.head == 1p; }
    134135              bool signal      ( condition & this );
    135136              bool signal_block( condition & this );
    136 static inline bool is_empty    ( condition & this ) { return this.blocked.head == 1p; }
     137static inline bool signal_all  ( condition & this ) { bool ret = false; while(!is_empty(this)) { ret = signal(this) || ret; } return ret; }
    137138         uintptr_t front       ( condition & this );
    138139
  • src/ResolvExpr/ResolveAssertions.cc

    r5a51798 r64aeca0  
    397397
    398398        /// Limit to depth of recursion of assertion satisfaction
    399         static const int recursionLimit = 4;
     399        static const int recursionLimit = 7;
    400400        /// Maximum number of simultaneously-deferred assertions to attempt concurrent satisfaction of
    401401        static const int deferLimit = 10;
  • src/ResolvExpr/SatisfyAssertions.cpp

    r5a51798 r64aeca0  
    5757                ast::UniqueId resnSlot;          ///< Slot for any recursive assertion IDs
    5858
    59                 AssnCandidate( 
    60                         const ast::SymbolTable::IdData c, const ast::Type * at, ast::TypeEnvironment && e, 
     59                AssnCandidate(
     60                        const ast::SymbolTable::IdData c, const ast::Type * at, ast::TypeEnvironment && e,
    6161                        ast::AssertionSet && h, ast::AssertionSet && n, ast::OpenVarSet && o, ast::UniqueId rs )
    62                 : cdata( c ), adjType( at ), env( std::move( e ) ), have( std::move( h ) ), 
     62                : cdata( c ), adjType( at ), env( std::move( e ) ), have( std::move( h ) ),
    6363                  need( std::move( n ) ), open( std::move( o ) ), resnSlot( rs ) {}
    6464        };
     
    7373                const AssnCandidate & match;
    7474        };
    75        
    76         /// Wrapper for the deferred items from a single assertion satisfaction. 
     75
     76        /// Wrapper for the deferred items from a single assertion satisfaction.
    7777        /// Acts like an indexed list of DeferRef
    7878        struct DeferItem {
     
    8181                AssnCandidateList matches;
    8282
    83                 DeferItem( 
     83                DeferItem(
    8484                        const ast::VariableExpr * d, const ast::AssertionSetValue & i, AssnCandidateList && ms )
    8585                : expr( d ), info( i ), matches( std::move( ms ) ) {}
     
    117117                /// Initial satisfaction state for a candidate
    118118                SatState( CandidateRef & c, const ast::SymbolTable & syms )
    119                 : cand( c ), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, 
     119                : cand( c ), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero },
    120120                  symtab( syms ) { need.swap( c->need ); }
    121                
     121
    122122                /// Update satisfaction state for next step after previous state
    123123                SatState( SatState && o, IterateFlag )
    124                 : cand( std::move( o.cand ) ), need( o.newNeed.begin(), o.newNeed.end() ), newNeed(), 
    125                   deferred(), inferred( std::move( o.inferred ) ), costs( std::move( o.costs ) ), 
     124                : cand( std::move( o.cand ) ), need( o.newNeed.begin(), o.newNeed.end() ), newNeed(),
     125                  deferred(), inferred( std::move( o.inferred ) ), costs( std::move( o.costs ) ),
    126126                  symtab( o.symtab ) { costs.emplace_back( Cost::zero ); }
    127                
     127
    128128                /// Field-wise next step constructor
    129129                SatState(
    130                         CandidateRef && c, ast::AssertionSet && nn, InferCache && i, CostVec && cs, 
     130                        CandidateRef && c, ast::AssertionSet && nn, InferCache && i, CostVec && cs,
    131131                        ast::SymbolTable && syms )
    132                 : cand( std::move( c ) ), need( nn.begin(), nn.end() ), newNeed(), deferred(), 
     132                : cand( std::move( c ) ), need( nn.begin(), nn.end() ), newNeed(), deferred(),
    133133                  inferred( std::move( i ) ), costs( std::move( cs ) ), symtab( std::move( syms ) )
    134134                  { costs.emplace_back( Cost::zero ); }
     
    143143
    144144        /// Binds a single assertion, updating satisfaction state
    145         void bindAssertion( 
    146                 const ast::VariableExpr * expr, const ast::AssertionSetValue & info, CandidateRef & cand, 
     145        void bindAssertion(
     146                const ast::VariableExpr * expr, const ast::AssertionSetValue & info, CandidateRef & cand,
    147147                AssnCandidate & match, InferCache & inferred
    148148        ) {
    149149                const ast::DeclWithType * candidate = match.cdata.id;
    150                 assertf( candidate->uniqueId, 
     150                assertf( candidate->uniqueId,
    151151                        "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    152                
     152
    153153                ast::Expr * varExpr = match.cdata.combine( cand->expr->location, cand->cvtCost );
    154154                varExpr->result = match.adjType;
     
    201201                        ast::OpenVarSet newOpen{ sat.cand->open };
    202202                        ast::ptr< ast::Type > toType = assn.first->result;
    203                         ast::ptr< ast::Type > adjType = 
     203                        ast::ptr< ast::Type > adjType =
    204204                                renameTyVars( adjustExprType( candidate->get_type(), newEnv, sat.symtab ), GEN_USAGE, false );
    205205
     
    213213                                }
    214214
    215                                 matches.emplace_back( 
     215                                matches.emplace_back(
    216216                                        cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ),
    217217                                        std::move( newOpen ), crntResnSlot );
     
    287287        };
    288288
    289         /// Replace ResnSlots with InferParams and add alternative to output list, if it meets pruning 
     289        /// Replace ResnSlots with InferParams and add alternative to output list, if it meets pruning
    290290        /// threshold.
    291         void finalizeAssertions( 
    292                 CandidateRef & cand, InferCache & inferred, PruneMap & thresholds, CostVec && costs, 
    293                 CandidateList & out 
     291        void finalizeAssertions(
     292                CandidateRef & cand, InferCache & inferred, PruneMap & thresholds, CostVec && costs,
     293                CandidateList & out
    294294        ) {
    295295                // prune if cheaper alternative for same key has already been generated
     
    308308        }
    309309
    310         /// Combo iterator that combines candidates into an output list, merging their environments. 
    311         /// Rejects an appended candidate if environments cannot be merged. See `Common/FilterCombos.h` 
     310        /// Combo iterator that combines candidates into an output list, merging their environments.
     311        /// Rejects an appended candidate if environments cannot be merged. See `Common/FilterCombos.h`
    312312        /// for description of "combo iterator".
    313313        class CandidateEnvMerger {
     
    390390} // anonymous namespace
    391391
    392 void satisfyAssertions( 
    393         CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out, 
     392void satisfyAssertions(
     393        CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out,
    394394        std::vector<std::string> & errors
    395395) {
     
    418418
    419419                        // should a limit be imposed? worst case here is O(n^2) but very unlikely to happen.
    420                         for (unsigned resetCount = 0; ; ++resetCount) { 
     420                        for (unsigned resetCount = 0; ; ++resetCount) {
    421421                                ast::AssertionList next;
    422422                                resetTyVarRenaming();
     
    449449                                // either add successful match or push back next state
    450450                                if ( sat.newNeed.empty() ) {
    451                                         finalizeAssertions( 
     451                                        finalizeAssertions(
    452452                                                sat.cand, sat.inferred, thresholds, std::move( sat.costs ), out );
    453453                                } else {
     
    471471                                std::vector< CandidateEnvMerger::OutType > compatible = filterCombos(
    472472                                        sat.deferred, CandidateEnvMerger{ sat.cand->env, sat.cand->open, sat.symtab } );
    473                                
     473
    474474                                // fail early if no mutually-compatible assertion satisfaction
    475475                                if ( compatible.empty() ) {
     
    494494                                        // set up next satisfaction state
    495495                                        CandidateRef nextCand = std::make_shared<Candidate>(
    496                                                 sat.cand->expr, std::move( compat.env ), std::move( compat.open ), 
     496                                                sat.cand->expr, std::move( compat.env ), std::move( compat.open ),
    497497                                                ast::AssertionSet{} /* need moved into satisfaction state */,
    498498                                                sat.cand->cost, sat.cand->cvtCost );
     
    500500                                        ast::AssertionSet nextNewNeed{ sat.newNeed };
    501501                                        InferCache nextInferred{ sat.inferred };
    502                                        
     502
    503503                                        CostVec nextCosts{ sat.costs };
    504504                                        nextCosts.back() += compat.cost;
    505                                                                
     505
    506506                                        ast::SymbolTable nextSymtab{ sat.symtab };
    507507
     
    517517                                        // either add successful match or push back next state
    518518                                        if ( nextNewNeed.empty() ) {
    519                                                 finalizeAssertions( 
     519                                                finalizeAssertions(
    520520                                                        nextCand, nextInferred, thresholds, std::move( nextCosts ), out );
    521521                                        } else {
    522                                                 nextSats.emplace_back( 
    523                                                         std::move( nextCand ), std::move( nextNewNeed ), 
    524                                                         std::move( nextInferred ), std::move( nextCosts ), 
     522                                                nextSats.emplace_back(
     523                                                        std::move( nextCand ), std::move( nextNewNeed ),
     524                                                        std::move( nextInferred ), std::move( nextCosts ),
    525525                                                        std::move( nextSymtab ) );
    526526                                        }
     
    534534                nextSats.clear();
    535535        }
    536        
     536
    537537        // exceeded recursion limit if reaches here
    538538        if ( out.empty() ) {
  • tests/concurrent/futures/.expect/basic.txt

    r5a51798 r64aeca0  
     1start
    12done
  • tests/concurrent/futures/basic.cfa

    r5a51798 r64aeca0  
    11#include <thread.hfa>
     2
    23enum {NFUTURES = 10};
    34
     
    8384
    8485int main() {
     86        printf( "start\n" );                            // non-empty .expect file
    8587        processor procs[2];
    8688        {
Note: See TracChangeset for help on using the changeset viewer.