Changes in / [0aef549:8421d3f]


Ignore:
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/colby_parsons_MMAth/text/channels.tex

    r0aef549 r8421d3f  
    1919It was the popularity of Go channels that lead to their implementation in \CFA.
    2020Neither 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.
    2721
    2822\section{Producer-Consumer Problem}
     
    237231\begin{lrbox}{\myboxB}
    238232\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 =======
    252233channel( size_t ) chan{ 128 };
    253234thread Consumer {};
    254235thread Producer {};
    255 >>>>>>> 8421d3fad6379460563c3a8922889a72c4d868fe
    256236
    257237void main( Producer & this ) {
  • libcfa/src/bits/weakso_locks.cfa

    r0aef549 r8421d3f  
    3030bool register_select( blocking_lock & this, select_node & node ) { return false; }
    3131bool unregister_select( blocking_lock & this, select_node & node ) { return false; }
    32 void on_selected( blocking_lock & this, select_node & node ) {}
     32bool on_selected( blocking_lock & this, select_node & node ) { return true; }
    3333
  • libcfa/src/bits/weakso_locks.hfa

    r0aef549 r8421d3f  
    6262bool register_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
    6363bool unregister_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
    64 void on_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
     64bool on_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
    6565
    6666//----------
     
    8080static inline bool   register_select( multiple_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    8181static inline bool   unregister_select( multiple_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    82 static inline void   on_selected( multiple_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
     82static inline bool   on_selected( multiple_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
  • libcfa/src/concurrency/channel.hfa

    r0aef549 r8421d3f  
    441441}
    442442static inline bool unregister_select( chan_read(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); }
    443 static inline void on_selected( chan_read(T) & this, select_node & node ) with(this) {
     443static inline bool on_selected( chan_read(T) & this, select_node & node ) with(this) {
    444444    if ( node.extra == 0p ) // check if woken up due to closed channel
    445445        __closed_remove( chan, ret );
    446446    // This is only reachable if not closed or closed exception was handled
     447    return true;
    447448}
    448449
     
    533534static inline bool unregister_select( chan_write(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); }
    534535
    535 static inline void on_selected( chan_write(T) & this, select_node & node ) with(this) {
     536static inline bool on_selected( chan_write(T) & this, select_node & node ) with(this) {
    536537    if ( node.extra == 0p ) // check if woken up due to closed channel
    537538        __closed_insert( chan, elem );
    538539
    539540    // This is only reachable if not closed or closed exception was handled
     541    return true;
    540542}
    541543
  • libcfa/src/concurrency/future.hfa

    r0aef549 r8421d3f  
    7070                // check if the future is available
    7171        // 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 __atomic_load_n( &this.state, __ATOMIC_RELAXED ); }
     72                bool available( future(T) & this ) { return this.state; }
    7373
    7474
     
    180180        }
    181181               
    182         void on_selected( future(T) & this, select_node & node ) {}
     182        bool on_selected( future(T) & this, select_node & node ) { return true; }
    183183        }
    184184}
    185185
    186186//--------------------------------------------------------------------------------------------------------
    187 // These futures below do not support select statements so they may not have as many features as 'future'
     187// These futures below do not support select statements so they may not be as useful as 'future'
    188188//  however the 'single_future' is cheap and cheerful and is most likely more performant than 'future'
    189189//  since it uses raw atomics and no locks
  • libcfa/src/concurrency/locks.cfa

    r0aef549 r8421d3f  
    239239}
    240240
    241 void on_selected( blocking_lock & this, select_node & node ) {}
     241bool on_selected( blocking_lock & this, select_node & node ) { return true; }
    242242
    243243//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/locks.hfa

    r0aef549 r8421d3f  
    114114static inline bool   register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    115115static inline bool   unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    116 static inline void   on_selected( single_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
     116static inline bool   on_selected( single_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
    117117
    118118//----------
     
    131131static inline bool   register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    132132static inline bool   unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    133 static inline void   on_selected( owner_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
     133static inline bool   on_selected( owner_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
    134134
    135135//-----------------------------------------------------------------------------
     
    621621}
    622622
    623 static inline void on_selected( simple_owner_lock & this, select_node & node ) {}
     623static inline bool on_selected( simple_owner_lock & this, select_node & node ) { return true; }
    624624
    625625
  • libcfa/src/concurrency/select.cfa

    r0aef549 r8421d3f  
    4949    return false;
    5050}
    51 void on_selected( select_timeout_node & this, select_node & node ) {}
     51bool on_selected( select_timeout_node & this, select_node & node ) { return true; }
    5252
    5353// Gateway routine to wait on duration
  • libcfa/src/concurrency/select.hfa

    r0aef549 r8421d3f  
    9191    // For unregistering a select stmt on a selectable concurrency primitive
    9292    // 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 &  );
    9494
    9595    // This routine is run on the selecting thread prior to executing the statement corresponding to the select_node
    9696    //    passed as an arg to this routine
    9797    // If on_selected returns false, the statement is not run, if it returns true it is run.
    98     void on_selected( T &, select_node & );
     98    bool on_selected( T &, select_node & );
    9999};
    100100
     
    208208bool register_select( select_timeout_node & this, select_node & node );
    209209bool unregister_select( select_timeout_node & this, select_node & node );
    210 void on_selected( select_timeout_node & this, select_node & node );
     210bool on_selected( select_timeout_node & this, select_node & node );
    211211
    212212// Gateway routines to waituntil on duration
  • src/Concurrency/Waituntil.cpp

    r0aef549 r8421d3f  
    9595                        case 0:
    9696                            try {
    97                                     on_selected( A, clause1 );
     97                                if (on_selected( A, clause1 ))
    9898                                    doA();
    9999                            }
     
    122122        // the unregister and on_selected calls are needed to support primitives where the acquire has side effects
    123123        // 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) )
    125             on_selected( A, clause1 )
     124        if ( ! has_run(clause_statuses[0]) && whenA && unregister_select(A, clause1) && on_selected( A, clause1 ) )
    126125            doA();
    127126        ... repeat if above for B and C ...
     
    620619
    621620// Generates:
    622 /* on_selected( target_1, node_1 ); ... corresponding body of target_1 ...
     621/* if ( on_selected( target_1, node_1 )) ... corresponding body of target_1 ...
    623622*/
    624623CompoundStmt * GenerateWaitUntilCore::genStmtBlock( const WhenClause * clause, const ClauseData * data ) {
     
    626625    return new CompoundStmt( cLoc,
    627626        {
    628             new ExprStmt( cLoc,
    629                 genSelectTraitCall( clause, data, "on_selected" )
    630             ),
    631             ast::deepCopy( clause->stmt )
     627            new IfStmt( cLoc,
     628                genSelectTraitCall( clause, data, "on_selected" ),
     629                new CompoundStmt( cLoc,
     630                    {
     631                        ast::deepCopy( clause->stmt )
     632                    }
     633                )
     634            )
    632635        }
    633636    );
     
    641644            case 0:
    642645                try {
    643                     on_selected( target1, clause1 );
    644                     dotarget1stmt();
     646                    if (on_selected( target1, clause1 ))
     647                        dotarget1stmt();
    645648                }
    646649                finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
     
    661664        case 0:
    662665            try {
    663                 on_selected( target1, clause1 );
    664                 dotarget1stmt();
     666                if (on_selected( target1, clause1 ))
     667                    dotarget1stmt();
    665668            }
    666669            finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
     
    10171020                ifCond,
    10181021                genStmtBlock( stmt->clauses.at(idx), data.at(idx) ),
     1022                // ast::deepCopy( stmt->clauses.at(idx)->stmt ),
    10191023                recursiveOrIfGen( stmt, data, idx + 1, elseWhenName )
    10201024            )
Note: See TracChangeset for help on using the changeset viewer.