Changeset 1f951abd for libcfa/src
- Timestamp:
- Mar 2, 2023, 2:09:58 PM (22 months ago)
- 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. - Location:
- libcfa/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/channel.hfa
r8bb46d2 r1f951abd 15 15 static inline void on_wakeup( no_reacq_lock & this, size_t recursion ) {} 16 16 17 #define __PREVENTION_CHANNEL 18 #ifdef __PREVENTION_CHANNEL 19 forall( T ) { 20 struct 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 30 static 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 40 static inline void ?{}( channel(T) &c ){ ((channel(T) &)c){ 0 }; } 41 static inline void ^?{}( channel(T) &c ) with(c) { delete( buffer ); } 42 static inline size_t get_count( channel(T) & chan ) with(chan) { return count; } 43 static inline size_t get_size( channel(T) & chan ) with(chan) { return size; } 44 static inline bool has_waiters( channel(T) & chan ) with(chan) { return chair != 0p; } 45 46 static 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 53 static 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 92 static 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 17 141 forall( T ) { 18 142 struct channel { … … 41 165 static inline bool has_waiting_producers( channel(T) & chan ) with(chan) { return !empty( prods ); } 42 166 43 static inline void insert_( channel(T) & chan, T elem ) with(chan) {167 static inline void insert_( channel(T) & chan, T & elem ) with(chan) { 44 168 memcpy((void *)&buffer[back], (void *)&elem, sizeof(T)); 45 169 count += 1; … … 107 231 108 232 } // forall( T ) 233 #endif -
libcfa/src/containers/array.hfa
r8bb46d2 r1f951abd 9 9 10 10 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 // 15 37 forall( [N], S & | sized(S), Timmed &, Tbase & ) { 38 39 // 40 // Single-dim array sruct (with explicit packing and atom) 41 // 16 42 struct arpk { 17 43 S strides[N];
Note: See TracChangeset
for help on using the changeset viewer.