Changes in / [8421d3f:0aef549]
- Files:
-
- 10 edited
-
doc/theses/colby_parsons_MMAth/text/channels.tex (modified) (2 diffs)
-
libcfa/src/bits/weakso_locks.cfa (modified) (1 diff)
-
libcfa/src/bits/weakso_locks.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/channel.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/future.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/locks.cfa (modified) (1 diff)
-
libcfa/src/concurrency/locks.hfa (modified) (3 diffs)
-
libcfa/src/concurrency/select.cfa (modified) (1 diff)
-
libcfa/src/concurrency/select.hfa (modified) (2 diffs)
-
src/Concurrency/Waituntil.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/colby_parsons_MMAth/text/channels.tex
r8421d3f r0aef549 19 19 It was the popularity of Go channels that lead to their implementation in \CFA. 20 20 Neither Go nor \CFA channels have the restrictions of the early channel-based concurrent systems. 21 22 Other popular languages and libraries that provide channels include C++ Boost~\cite{boost:channel}, Rust~\cite{rust:channel}, Haskell~\cite{haskell:channel}, and OCaml~\cite{ocaml:channel}. 23 Boost channels only support asynchronous (non-blocking) operations, and Rust channels are limited to only having one consumer per channel. 24 Haskell channels are unbounded in size, and OCaml channels are zero-size. 25 These restrictions in Haskell and OCaml are likely due to their functional approach, which results in them both using a list as the underlying data structure for their channel. 26 These languages and libraries are not discussed further, as their channel implementation is not comparable to the bounded-buffer style channels present in Go and \CFA. 21 27 22 28 \section{Producer-Consumer Problem} … … 231 237 \begin{lrbox}{\myboxB} 232 238 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 239 <<<<<<< HEAD 240 var cons_done, prod_done bool = false, false; 241 var prodJoin chan int = make(chan int) 242 var consJoin chan int = make(chan int) 243 244 func consumer( channel chan uint64 ) { 245 for { 246 if cons_done { break } 247 <-channel 248 } 249 consJoin <- 0 // synch with main thd 250 } 251 ======= 233 252 channel( size_t ) chan{ 128 }; 234 253 thread Consumer {}; 235 254 thread Producer {}; 255 >>>>>>> 8421d3fad6379460563c3a8922889a72c4d868fe 236 256 237 257 void main( Producer & this ) { -
libcfa/src/bits/weakso_locks.cfa
r8421d3f r0aef549 30 30 bool register_select( blocking_lock & this, select_node & node ) { return false; } 31 31 bool unregister_select( blocking_lock & this, select_node & node ) { return false; } 32 bool on_selected( blocking_lock & this, select_node & node ) { return true;}32 void on_selected( blocking_lock & this, select_node & node ) {} 33 33 -
libcfa/src/bits/weakso_locks.hfa
r8421d3f r0aef549 62 62 bool register_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD; 63 63 bool unregister_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD; 64 boolon_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;64 void on_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD; 65 65 66 66 //---------- … … 80 80 static inline bool register_select( multiple_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); } 81 81 static inline bool unregister_select( multiple_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); } 82 static inline bool on_selected( multiple_acquisition_lock & this, select_node & node ) { returnon_selected( (blocking_lock &)this, node ); }82 static inline void on_selected( multiple_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } -
libcfa/src/concurrency/channel.hfa
r8421d3f r0aef549 441 441 } 442 442 static inline bool unregister_select( chan_read(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); } 443 static inline boolon_selected( chan_read(T) & this, select_node & node ) with(this) {443 static inline void on_selected( chan_read(T) & this, select_node & node ) with(this) { 444 444 if ( node.extra == 0p ) // check if woken up due to closed channel 445 445 __closed_remove( chan, ret ); 446 446 // This is only reachable if not closed or closed exception was handled 447 return true;448 447 } 449 448 … … 534 533 static inline bool unregister_select( chan_write(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); } 535 534 536 static inline boolon_selected( chan_write(T) & this, select_node & node ) with(this) {535 static inline void on_selected( chan_write(T) & this, select_node & node ) with(this) { 537 536 if ( node.extra == 0p ) // check if woken up due to closed channel 538 537 __closed_insert( chan, elem ); 539 538 540 539 // This is only reachable if not closed or closed exception was handled 541 return true;542 540 } 543 541 -
libcfa/src/concurrency/future.hfa
r8421d3f r0aef549 70 70 // check if the future is available 71 71 // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected 72 bool available( future(T) & this ) { return this.state; }72 bool available( future(T) & this ) { return __atomic_load_n( &this.state, __ATOMIC_RELAXED ); } 73 73 74 74 … … 180 180 } 181 181 182 bool on_selected( future(T) & this, select_node & node ) { return true;}182 void on_selected( future(T) & this, select_node & node ) {} 183 183 } 184 184 } 185 185 186 186 //-------------------------------------------------------------------------------------------------------- 187 // These futures below do not support select statements so they may not be as usefulas 'future'187 // These futures below do not support select statements so they may not have as many features as 'future' 188 188 // however the 'single_future' is cheap and cheerful and is most likely more performant than 'future' 189 189 // since it uses raw atomics and no locks -
libcfa/src/concurrency/locks.cfa
r8421d3f r0aef549 239 239 } 240 240 241 bool on_selected( blocking_lock & this, select_node & node ) { return true;}241 void on_selected( blocking_lock & this, select_node & node ) {} 242 242 243 243 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/locks.hfa
r8421d3f r0aef549 114 114 static inline bool register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); } 115 115 static inline bool unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); } 116 static inline bool on_selected( single_acquisition_lock & this, select_node & node ) { returnon_selected( (blocking_lock &)this, node ); }116 static inline void on_selected( single_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } 117 117 118 118 //---------- … … 131 131 static inline bool register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); } 132 132 static inline bool unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); } 133 static inline bool on_selected( owner_lock & this, select_node & node ) { returnon_selected( (blocking_lock &)this, node ); }133 static inline void on_selected( owner_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } 134 134 135 135 //----------------------------------------------------------------------------- … … 621 621 } 622 622 623 static inline bool on_selected( simple_owner_lock & this, select_node & node ) { return true;}623 static inline void on_selected( simple_owner_lock & this, select_node & node ) {} 624 624 625 625 -
libcfa/src/concurrency/select.cfa
r8421d3f r0aef549 49 49 return false; 50 50 } 51 bool on_selected( select_timeout_node & this, select_node & node ) { return true;}51 void on_selected( select_timeout_node & this, select_node & node ) {} 52 52 53 53 // Gateway routine to wait on duration -
libcfa/src/concurrency/select.hfa
r8421d3f r0aef549 91 91 // For unregistering a select stmt on a selectable concurrency primitive 92 92 // If true is returned then the corresponding code block is run (only in non-special OR case and only if node status is not RUN) 93 bool unregister_select( T &, select_node & );93 bool unregister_select( T &, select_node & ); 94 94 95 95 // This routine is run on the selecting thread prior to executing the statement corresponding to the select_node 96 96 // passed as an arg to this routine 97 97 // If on_selected returns false, the statement is not run, if it returns true it is run. 98 boolon_selected( T &, select_node & );98 void on_selected( T &, select_node & ); 99 99 }; 100 100 … … 208 208 bool register_select( select_timeout_node & this, select_node & node ); 209 209 bool unregister_select( select_timeout_node & this, select_node & node ); 210 boolon_selected( select_timeout_node & this, select_node & node );210 void on_selected( select_timeout_node & this, select_node & node ); 211 211 212 212 // Gateway routines to waituntil on duration -
src/Concurrency/Waituntil.cpp
r8421d3f r0aef549 95 95 case 0: 96 96 try { 97 if (on_selected( A, clause1 ))97 on_selected( A, clause1 ); 98 98 doA(); 99 99 } … … 122 122 // the unregister and on_selected calls are needed to support primitives where the acquire has side effects 123 123 // so the corresponding block MUST be run for those primitives to not lose state (example is channels) 124 if ( ! has_run(clause_statuses[0]) && whenA && unregister_select(A, clause1) && on_selected( A, clause1 ) ) 124 if ( !has_run(clause_statuses[0]) && whenA && unregister_select(A, clause1) ) 125 on_selected( A, clause1 ) 125 126 doA(); 126 127 ... repeat if above for B and C ... … … 619 620 620 621 // Generates: 621 /* if ( on_selected( target_1, node_1 ))... corresponding body of target_1 ...622 /* on_selected( target_1, node_1 ); ... corresponding body of target_1 ... 622 623 */ 623 624 CompoundStmt * GenerateWaitUntilCore::genStmtBlock( const WhenClause * clause, const ClauseData * data ) { … … 625 626 return new CompoundStmt( cLoc, 626 627 { 627 new IfStmt( cLoc, 628 genSelectTraitCall( clause, data, "on_selected" ), 629 new CompoundStmt( cLoc, 630 { 631 ast::deepCopy( clause->stmt ) 632 } 633 ) 634 ) 628 new ExprStmt( cLoc, 629 genSelectTraitCall( clause, data, "on_selected" ) 630 ), 631 ast::deepCopy( clause->stmt ) 635 632 } 636 633 ); … … 644 641 case 0: 645 642 try { 646 if (on_selected( target1, clause1 ))647 dotarget1stmt();643 on_selected( target1, clause1 ); 644 dotarget1stmt(); 648 645 } 649 646 finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); } … … 664 661 case 0: 665 662 try { 666 if (on_selected( target1, clause1 ))667 dotarget1stmt();663 on_selected( target1, clause1 ); 664 dotarget1stmt(); 668 665 } 669 666 finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); } … … 1020 1017 ifCond, 1021 1018 genStmtBlock( stmt->clauses.at(idx), data.at(idx) ), 1022 // ast::deepCopy( stmt->clauses.at(idx)->stmt ),1023 1019 recursiveOrIfGen( stmt, data, idx + 1, elseWhenName ) 1024 1020 )
Note:
See TracChangeset
for help on using the changeset viewer.