Changeset 64aeca0
- Timestamp:
- Jan 10, 2021, 5:47:16 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- 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. - Files:
-
- 36 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/creation/node_cor.js
r5a51798 r64aeca0 6 6 function * coroutine() { yield } 7 7 8 for ( var i = 0; i < times; i += 1 ) { // warm jit8 for ( var i = 0; i < times; i += 1 ) { // warm JIT 9 9 cor = coroutine() 10 10 } -
benchmark/ctxswitch/node_cor.js
r5a51798 r64aeca0 11 11 cor = coroutine() 12 12 13 for ( var i = 0; i < times; i += 1 ) { // warm git13 for ( var i = 0; i < times; i += 1 ) { // warm JIT 14 14 cor.next(); 15 15 } -
libcfa/src/Makefile.am
r5a51798 r64aeca0 58 58 concurrency/iofwd.hfa \ 59 59 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 61 65 62 66 inst_headers_src = \ … … 94 98 concurrency/clib/cfathread.h \ 95 99 concurrency/invoke.h \ 100 concurrency/future.hfa \ 96 101 concurrency/kernel/fwd.hfa 97 102 -
libcfa/src/bits/locks.hfa
r5a51798 r64aeca0 283 283 void ^?{}(future_t &) {} 284 284 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 285 290 // check if the future is available 286 291 bool available( future_t & this ) { … … 340 345 341 346 // 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 343 351 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; 344 355 345 356 // got == 2p: the future is ready but the context hasn't fully been consumed … … 347 358 if( got == 2p ) { 348 359 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; 351 367 } 352 368 -
libcfa/src/concurrency/monitor.hfa
r5a51798 r64aeca0 132 132 133 133 void wait ( condition & this, uintptr_t user_info = 0 ); 134 static inline bool is_empty ( condition & this ) { return this.blocked.head == 1p; } 134 135 bool signal ( condition & this ); 135 136 bool signal_block( condition & this ); 136 static inline bool is_empty ( condition & this ) { return this.blocked.head == 1p; }137 static inline bool signal_all ( condition & this ) { bool ret = false; while(!is_empty(this)) { ret = signal(this) || ret; } return ret; } 137 138 uintptr_t front ( condition & this ); 138 139 -
src/ResolvExpr/ResolveAssertions.cc
r5a51798 r64aeca0 397 397 398 398 /// Limit to depth of recursion of assertion satisfaction 399 static const int recursionLimit = 4;399 static const int recursionLimit = 7; 400 400 /// Maximum number of simultaneously-deferred assertions to attempt concurrent satisfaction of 401 401 static const int deferLimit = 10; -
src/ResolvExpr/SatisfyAssertions.cpp
r5a51798 r64aeca0 57 57 ast::UniqueId resnSlot; ///< Slot for any recursive assertion IDs 58 58 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, 61 61 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 ) ), 63 63 need( std::move( n ) ), open( std::move( o ) ), resnSlot( rs ) {} 64 64 }; … … 73 73 const AssnCandidate & match; 74 74 }; 75 76 /// Wrapper for the deferred items from a single assertion satisfaction. 75 76 /// Wrapper for the deferred items from a single assertion satisfaction. 77 77 /// Acts like an indexed list of DeferRef 78 78 struct DeferItem { … … 81 81 AssnCandidateList matches; 82 82 83 DeferItem( 83 DeferItem( 84 84 const ast::VariableExpr * d, const ast::AssertionSetValue & i, AssnCandidateList && ms ) 85 85 : expr( d ), info( i ), matches( std::move( ms ) ) {} … … 117 117 /// Initial satisfaction state for a candidate 118 118 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 }, 120 120 symtab( syms ) { need.swap( c->need ); } 121 121 122 122 /// Update satisfaction state for next step after previous state 123 123 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 ) ), 126 126 symtab( o.symtab ) { costs.emplace_back( Cost::zero ); } 127 127 128 128 /// Field-wise next step constructor 129 129 SatState( 130 CandidateRef && c, ast::AssertionSet && nn, InferCache && i, CostVec && cs, 130 CandidateRef && c, ast::AssertionSet && nn, InferCache && i, CostVec && cs, 131 131 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(), 133 133 inferred( std::move( i ) ), costs( std::move( cs ) ), symtab( std::move( syms ) ) 134 134 { costs.emplace_back( Cost::zero ); } … … 143 143 144 144 /// 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, 147 147 AssnCandidate & match, InferCache & inferred 148 148 ) { 149 149 const ast::DeclWithType * candidate = match.cdata.id; 150 assertf( candidate->uniqueId, 150 assertf( candidate->uniqueId, 151 151 "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 152 152 153 153 ast::Expr * varExpr = match.cdata.combine( cand->expr->location, cand->cvtCost ); 154 154 varExpr->result = match.adjType; … … 201 201 ast::OpenVarSet newOpen{ sat.cand->open }; 202 202 ast::ptr< ast::Type > toType = assn.first->result; 203 ast::ptr< ast::Type > adjType = 203 ast::ptr< ast::Type > adjType = 204 204 renameTyVars( adjustExprType( candidate->get_type(), newEnv, sat.symtab ), GEN_USAGE, false ); 205 205 … … 213 213 } 214 214 215 matches.emplace_back( 215 matches.emplace_back( 216 216 cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ), 217 217 std::move( newOpen ), crntResnSlot ); … … 287 287 }; 288 288 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 290 290 /// 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 294 294 ) { 295 295 // prune if cheaper alternative for same key has already been generated … … 308 308 } 309 309 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` 312 312 /// for description of "combo iterator". 313 313 class CandidateEnvMerger { … … 390 390 } // anonymous namespace 391 391 392 void satisfyAssertions( 393 CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out, 392 void satisfyAssertions( 393 CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out, 394 394 std::vector<std::string> & errors 395 395 ) { … … 418 418 419 419 // 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) { 421 421 ast::AssertionList next; 422 422 resetTyVarRenaming(); … … 449 449 // either add successful match or push back next state 450 450 if ( sat.newNeed.empty() ) { 451 finalizeAssertions( 451 finalizeAssertions( 452 452 sat.cand, sat.inferred, thresholds, std::move( sat.costs ), out ); 453 453 } else { … … 471 471 std::vector< CandidateEnvMerger::OutType > compatible = filterCombos( 472 472 sat.deferred, CandidateEnvMerger{ sat.cand->env, sat.cand->open, sat.symtab } ); 473 473 474 474 // fail early if no mutually-compatible assertion satisfaction 475 475 if ( compatible.empty() ) { … … 494 494 // set up next satisfaction state 495 495 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 ), 497 497 ast::AssertionSet{} /* need moved into satisfaction state */, 498 498 sat.cand->cost, sat.cand->cvtCost ); … … 500 500 ast::AssertionSet nextNewNeed{ sat.newNeed }; 501 501 InferCache nextInferred{ sat.inferred }; 502 502 503 503 CostVec nextCosts{ sat.costs }; 504 504 nextCosts.back() += compat.cost; 505 505 506 506 ast::SymbolTable nextSymtab{ sat.symtab }; 507 507 … … 517 517 // either add successful match or push back next state 518 518 if ( nextNewNeed.empty() ) { 519 finalizeAssertions( 519 finalizeAssertions( 520 520 nextCand, nextInferred, thresholds, std::move( nextCosts ), out ); 521 521 } 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 ), 525 525 std::move( nextSymtab ) ); 526 526 } … … 534 534 nextSats.clear(); 535 535 } 536 536 537 537 // exceeded recursion limit if reaches here 538 538 if ( out.empty() ) { -
tests/concurrent/futures/.expect/basic.txt
r5a51798 r64aeca0 1 start 1 2 done -
tests/concurrent/futures/basic.cfa
r5a51798 r64aeca0 1 1 #include <thread.hfa> 2 2 3 enum {NFUTURES = 10}; 3 4 … … 83 84 84 85 int main() { 86 printf( "start\n" ); // non-empty .expect file 85 87 processor procs[2]; 86 88 {
Note: See TracChangeset
for help on using the changeset viewer.