Changeset 1f951abd for libcfa/src


Ignore:
Timestamp:
Mar 2, 2023, 2:09:58 PM (15 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
397c4392
Parents:
8bb46d2 (diff), 997324c (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

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/channel.hfa

    r8bb46d2 r1f951abd  
    1515static inline void   on_wakeup( no_reacq_lock & this, size_t recursion ) {}
    1616
     17#define __PREVENTION_CHANNEL
     18#ifdef __PREVENTION_CHANNEL
     19forall( T ) {
     20struct channel {
     21    size_t size;
     22    size_t front, back, count;
     23    T * buffer;
     24    thread$ * chair;
     25    T * chair_elem;
     26    exp_backoff_then_block_lock c_lock, p_lock;
     27    __spinlock_t mutex_lock;
     28};
     29
     30static inline void ?{}( channel(T) &c, size_t _size ) with(c) {
     31    size = _size;
     32    front = back = count = 0;
     33    buffer = anew( size );
     34    chair = 0p;
     35    mutex_lock{};
     36    c_lock{};
     37    p_lock{};
     38}
     39
     40static inline void ?{}( channel(T) &c ){ ((channel(T) &)c){ 0 }; }
     41static inline void ^?{}( channel(T) &c ) with(c) { delete( buffer ); }
     42static inline size_t get_count( channel(T) & chan ) with(chan) { return count; }
     43static inline size_t get_size( channel(T) & chan ) with(chan) { return size; }
     44static inline bool has_waiters( channel(T) & chan ) with(chan) { return chair != 0p; }
     45
     46static inline void insert_( channel(T) & chan, T & elem ) with(chan) {
     47    memcpy((void *)&buffer[back], (void *)&elem, sizeof(T));
     48    count += 1;
     49    back++;
     50    if ( back == size ) back = 0;
     51}
     52
     53static inline void insert( channel(T) & chan, T elem ) with( chan ) {
     54    lock( p_lock );
     55    lock( mutex_lock __cfaabi_dbg_ctx2 );
     56
     57    // have to check for the zero size channel case
     58    if ( size == 0 && chair != 0p ) {
     59        memcpy((void *)chair_elem, (void *)&elem, sizeof(T));
     60        unpark( chair );
     61        chair = 0p;
     62        unlock( mutex_lock );
     63        unlock( p_lock );
     64        unlock( c_lock );
     65        return;
     66    }
     67
     68    // wait if buffer is full, work will be completed by someone else
     69    if ( count == size ) {
     70        chair = active_thread();
     71        chair_elem = &elem;
     72        unlock( mutex_lock );
     73        park( );
     74        return;
     75    } // if
     76
     77    if ( chair != 0p ) {
     78        memcpy((void *)chair_elem, (void *)&elem, sizeof(T));
     79        unpark( chair );
     80        chair = 0p;
     81        unlock( mutex_lock );
     82        unlock( p_lock );
     83        unlock( c_lock );
     84        return;
     85    }
     86    else insert_( chan, elem );
     87
     88    unlock( mutex_lock );
     89    unlock( p_lock );
     90}
     91
     92static inline T remove( channel(T) & chan ) with(chan) {
     93    lock( c_lock );
     94    lock( mutex_lock __cfaabi_dbg_ctx2 );
     95    T retval;
     96
     97    // have to check for the zero size channel case
     98    if ( size == 0 && chair != 0p ) {
     99        memcpy((void *)&retval, (void *)chair_elem, sizeof(T));
     100        unpark( chair );
     101        chair = 0p;
     102        unlock( mutex_lock );
     103        unlock( p_lock );
     104        unlock( c_lock );
     105        return retval;
     106    }
     107
     108    // wait if buffer is empty, work will be completed by someone else
     109    if ( count == 0 ) {
     110        chair = active_thread();
     111        chair_elem = &retval;
     112        unlock( mutex_lock );
     113        park( );
     114        return retval;
     115    }
     116
     117    // Remove from buffer
     118    memcpy((void *)&retval, (void *)&buffer[front], sizeof(T));
     119    count -= 1;
     120    front = (front + 1) % size;
     121
     122    if ( chair != 0p ) {
     123        insert_( chan, *chair_elem );  // do waiting producer work
     124        unpark( chair );
     125        chair = 0p;
     126        unlock( mutex_lock );
     127        unlock( p_lock );
     128        unlock( c_lock );
     129        return retval;
     130    }
     131
     132    unlock( mutex_lock );
     133    unlock( c_lock );
     134    return retval;
     135}
     136
     137} // forall( T )
     138#endif
     139
     140#ifndef __PREVENTION_CHANNEL
    17141forall( T ) {
    18142struct channel {
     
    41165static inline bool has_waiting_producers( channel(T) & chan ) with(chan) { return !empty( prods ); }
    42166
    43 static inline void insert_( channel(T) & chan, T elem ) with(chan) {
     167static inline void insert_( channel(T) & chan, T & elem ) with(chan) {
    44168    memcpy((void *)&buffer[back], (void *)&elem, sizeof(T));
    45169    count += 1;
     
    107231
    108232} // forall( T )
     233#endif
  • libcfa/src/containers/array.hfa

    r8bb46d2 r1f951abd  
    99
    1010
    11 //
    12 // Single-dim array sruct (with explicit packing and atom)
    13 //
    14 
     11//
     12// The `array` macro is the public interface.
     13// It computes the type of a dense (trivially strided) array.
     14// All user-declared objects are dense arrays.
     15//
     16// The `arpk` (ARray with PacKing info explicit) type is, generally, a slice with _any_ striding.
     17// This type is meant for internal use.
     18// CFA programmers should not instantiate it directly, nor access its field.
     19// CFA programmers should call ?[?] on it.
     20// Yet user-given `array(stuff)` expands to `arpk(stuff')`.
     21// The comments here explain the resulting internals.
     22//
     23// Just as a plain-C "multidimesional" array is really array-of-array-of-...,
     24// so does arpk generally show up as arpk-of-arpk-of...
     25//
     26// In the example of `array(float, 3, 4, 5) a;`,
     27// `typeof(a)` is an `arpk` instantiation.
     28// These comments explain _its_ arguments, i.e. those of the topmost `arpk` level.
     29//
     30// [N]    : the number of elements in `a`; 3 in the example
     31// S      : carries the stride size (distance in bytes between &myA[0] and &myA[1]), in sizeof(S);
     32//          same as Timmed when striding is trivial, same as Timmed in the example
     33// Timmed : (T-immediate) the inner type; conceptually, `typeof(a)` is "arpk of Timmed";
     34//          array(float, 4, 5) in the example
     35// Tbase  : (T-base) the deepest element type that is not arpk; float in the example
     36//
    1537forall( [N], S & | sized(S), Timmed &, Tbase & ) {
     38
     39    //
     40    // Single-dim array sruct (with explicit packing and atom)
     41    //
    1642    struct arpk {
    1743        S strides[N];
Note: See TracChangeset for help on using the changeset viewer.