Changes in / [8421d3f:0aef549]


Ignore:
Files:
10 edited

Legend:

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

    r8421d3f r0aef549  
    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
     22Other 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}.
     23Boost channels only support asynchronous (non-blocking) operations, and Rust channels are limited to only having one consumer per channel.
     24Haskell channels are unbounded in size, and OCaml channels are zero-size.
     25These 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.
     26These 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.
    2127
    2228\section{Producer-Consumer Problem}
     
    231237\begin{lrbox}{\myboxB}
    232238\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     239<<<<<<< HEAD
     240var cons_done, prod_done bool = false, false;
     241var prodJoin chan int = make(chan int)
     242var consJoin chan int = make(chan int)
     243
     244func consumer( channel chan uint64 ) {
     245    for {
     246        if cons_done { break }
     247        <-channel
     248    }
     249    consJoin <- 0 // synch with main thd
     250}
     251=======
    233252channel( size_t ) chan{ 128 };
    234253thread Consumer {};
    235254thread Producer {};
     255>>>>>>> 8421d3fad6379460563c3a8922889a72c4d868fe
    236256
    237257void main( Producer & this ) {
  • libcfa/src/bits/weakso_locks.cfa

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

    r8421d3f r0aef549  
    6262bool register_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
    6363bool unregister_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
    64 bool on_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;
     64void 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 bool   on_selected( multiple_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
     82static inline void   on_selected( multiple_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
  • libcfa/src/concurrency/channel.hfa

    r8421d3f r0aef549  
    441441}
    442442static inline bool unregister_select( chan_read(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); }
    443 static inline bool on_selected( chan_read(T) & this, select_node & node ) with(this) {
     443static inline void 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;
    448447}
    449448
     
    534533static inline bool unregister_select( chan_write(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); }
    535534
    536 static inline bool on_selected( chan_write(T) & this, select_node & node ) with(this) {
     535static inline void on_selected( chan_write(T) & this, select_node & node ) with(this) {
    537536    if ( node.extra == 0p ) // check if woken up due to closed channel
    538537        __closed_insert( chan, elem );
    539538
    540539    // This is only reachable if not closed or closed exception was handled
    541     return true;
    542540}
    543541
  • libcfa/src/concurrency/future.hfa

    r8421d3f r0aef549  
    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 this.state; }
     72                bool available( future(T) & this ) { return __atomic_load_n( &this.state, __ATOMIC_RELAXED ); }
    7373
    7474
     
    180180        }
    181181               
    182         bool on_selected( future(T) & this, select_node & node ) { return true; }
     182        void on_selected( future(T) & this, select_node & node ) {}
    183183        }
    184184}
    185185
    186186//--------------------------------------------------------------------------------------------------------
    187 // These futures below do not support select statements so they may not be as useful as 'future'
     187// These futures below do not support select statements so they may not have as many features 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

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

    r8421d3f r0aef549  
    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 bool   on_selected( single_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
     116static inline void   on_selected( single_acquisition_lock & this, select_node & node ) { 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 bool   on_selected( owner_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
     133static inline void   on_selected( owner_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
    134134
    135135//-----------------------------------------------------------------------------
     
    621621}
    622622
    623 static inline bool on_selected( simple_owner_lock & this, select_node & node ) { return true; }
     623static inline void on_selected( simple_owner_lock & this, select_node & node ) {}
    624624
    625625
  • libcfa/src/concurrency/select.cfa

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

    r8421d3f r0aef549  
    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     bool on_selected( T &, select_node & );
     98    void 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 bool on_selected( select_timeout_node & this, select_node & node );
     210void on_selected( select_timeout_node & this, select_node & node );
    211211
    212212// Gateway routines to waituntil on duration
  • src/Concurrency/Waituntil.cpp

    r8421d3f r0aef549  
    9595                        case 0:
    9696                            try {
    97                                 if (on_selected( A, clause1 ))
     97                                    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) && on_selected( A, clause1 ) )
     124        if ( !has_run(clause_statuses[0]) && whenA && unregister_select(A, clause1) )
     125            on_selected( A, clause1 )
    125126            doA();
    126127        ... repeat if above for B and C ...
     
    619620
    620621// 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 ...
    622623*/
    623624CompoundStmt * GenerateWaitUntilCore::genStmtBlock( const WhenClause * clause, const ClauseData * data ) {
     
    625626    return new CompoundStmt( cLoc,
    626627        {
    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 )
    635632        }
    636633    );
     
    644641            case 0:
    645642                try {
    646                     if (on_selected( target1, clause1 ))
    647                         dotarget1stmt();
     643                    on_selected( target1, clause1 );
     644                    dotarget1stmt();
    648645                }
    649646                finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
     
    664661        case 0:
    665662            try {
    666                 if (on_selected( target1, clause1 ))
    667                     dotarget1stmt();
     663                on_selected( target1, clause1 );
     664                dotarget1stmt();
    668665            }
    669666            finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
     
    10201017                ifCond,
    10211018                genStmtBlock( stmt->clauses.at(idx), data.at(idx) ),
    1022                 // ast::deepCopy( stmt->clauses.at(idx)->stmt ),
    10231019                recursiveOrIfGen( stmt, data, idx + 1, elseWhenName )
    10241020            )
Note: See TracChangeset for help on using the changeset viewer.