Changeset fc12f05 for libcfa/src/concurrency
- Timestamp:
- Nov 13, 2023, 3:43:43 AM (2 years ago)
- Branches:
- master
- Children:
- 25f2798
- Parents:
- 0030b508 (diff), 2174191 (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/concurrency
- Files:
-
- 5 edited
-
channel.hfa (modified) (2 diffs)
-
cofor.cfa (modified) (3 diffs)
-
cofor.hfa (modified) (3 diffs)
-
kernel.hfa (modified) (1 diff)
-
locks.hfa (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/channel.hfa
r0030b508 rfc12f05 130 130 static inline void __cons_handoff( channel(T) & chan, T & elem ) with(chan) { 131 131 memcpy( cons`first.extra, (void *)&elem, sizeof(T) ); // do waiting consumer work 132 __atomic_thread_fence( __ATOMIC_SEQ_CST );133 132 wake_one( cons ); 134 133 } … … 137 136 static inline void __prods_handoff( channel(T) & chan, T & retval ) with(chan) { 138 137 memcpy( (void *)&retval, prods`first.extra, sizeof(T) ); 139 __atomic_thread_fence( __ATOMIC_SEQ_CST );140 138 wake_one( prods ); 141 139 } -
libcfa/src/concurrency/cofor.cfa
r0030b508 rfc12f05 4 4 // cofor ( uC++ COFOR ) 5 5 6 thread cofor_ runner{6 thread cofor_task { 7 7 ssize_t low, high; 8 8 __cofor_body_t loop_body; 9 9 }; 10 10 11 static void ?{}( cofor_ runner& this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) {11 static void ?{}( cofor_task & this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) { 12 12 this.low = low; 13 13 this.high = high; … … 15 15 } 16 16 17 void main( cofor_ runner& this ) with( this ) {17 void main( cofor_task & this ) with( this ) { 18 18 for ( ssize_t i = low; i < high; i++ ) 19 19 loop_body(i); … … 29 29 ssize_t i = 0; 30 30 ssize_t stride_iter = low; 31 cofor_ runner* runners[ threads ];31 cofor_task * runners[ threads ]; 32 32 for ( i; threads ) { 33 33 runners[i] = alloc(); -
libcfa/src/concurrency/cofor.hfa
r0030b508 rfc12f05 1 1 #include <thread.hfa> 2 #include <locks.hfa> 3 #include <list.hfa> 2 4 3 5 ////////////////////////////////////////////////////////////////////////////////////////// … … 14 16 __Cofor__( low, high, __CFA_loopLambda__ ); \ 15 17 } 18 19 struct runner_node { 20 void * value; 21 inline dlink(runner_node); 22 }; 23 P9_EMBEDDED( runner_node, dlink(runner_node) ) 24 25 thread cofor_runner { 26 go_mutex mutex_lock; // MX lock 27 dlist( runner_node ) items; 28 void (*func)(void *); 29 volatile bool done; 30 }; 31 32 void ?{}( cofor_runner & this ) { this.done = false; } 33 34 void main( cofor_runner & this ) with(this) { 35 while ( !done || !items`isEmpty ) { 36 lock( mutex_lock ); 37 runner_node * node = &try_pop_front( items ); 38 unlock( mutex_lock ); 39 func( node->value ); 40 free( node->value ); 41 free( node ); 42 } 43 } 44 45 void start_runners( cofor_runner * thds, unsigned nprocs, void (*func)(void *) ) { 46 for ( i; nprocs ) { 47 thds[i].func = func; 48 } 49 } 50 51 void end_runners( cofor_runner * thds, unsigned nprocs ) { 52 for ( i; nprocs ) { 53 thds[i].done = true; 54 } 55 } 56 57 void send_work( cofor_runner * thds, unsigned nprocs, unsigned & curr_proc, void * value ) { 58 runner_node * node = malloc(); 59 (*node){}; 60 node->value = value; 61 lock( thds[curr_proc].mutex_lock ); 62 insert_last( thds[curr_proc].items, *node ); 63 unlock( thds[curr_proc].mutex_lock ); 64 curr_proc = ( curr_proc + 1 ) % nprocs; 65 } 16 66 17 67 ////////////////////////////////////////////////////////////////////////////////////////// … … 42 92 delete( this.runner ); 43 93 } 44 -
libcfa/src/concurrency/kernel.hfa
r0030b508 rfc12f05 303 303 // gets the number of constructed processors on the cluster 304 304 static inline unsigned get_proc_count( cluster & this ) { return this.procs.constructed; } 305 static inline unsigned get_proc_count() { return publicTLS_get( this_processor )->cltr->procs.constructed; } 305 306 306 307 // set the number of internal processors -
libcfa/src/concurrency/locks.hfa
r0030b508 rfc12f05 182 182 static inline void lock( mcs_spin_lock & l, mcs_spin_node & n ) { 183 183 n.locked = true; 184 185 #if defined(__ARM_ARCH) 186 __asm__ __volatile__ ( "DMB ISH" ::: ); 187 #endif 188 184 189 mcs_spin_node * prev = __atomic_exchange_n(&l.queue.tail, &n, __ATOMIC_SEQ_CST); 185 190 if( prev == 0p ) return; 186 191 prev->next = &n; 192 193 #if defined(__ARM_ARCH) 194 __asm__ __volatile__ ( "DMB ISH" ::: ); 195 #endif 196 187 197 while( __atomic_load_n(&n.locked, __ATOMIC_RELAXED) ) Pause(); 198 199 #if defined(__ARM_ARCH) 200 __asm__ __volatile__ ( "DMB ISH" ::: ); 201 #endif 188 202 } 189 203 190 204 static inline void unlock(mcs_spin_lock & l, mcs_spin_node & n) { 205 #if defined(__ARM_ARCH) 206 __asm__ __volatile__ ( "DMB ISH" ::: ); 207 #endif 208 191 209 mcs_spin_node * n_ptr = &n; 192 210 if (__atomic_compare_exchange_n(&l.queue.tail, &n_ptr, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) return; 193 211 while (__atomic_load_n(&n.next, __ATOMIC_RELAXED) == 0p) Pause(); 212 213 #if defined(__ARM_ARCH) 214 __asm__ __volatile__ ( "DMB ISH" ::: ); 215 #endif 216 194 217 n.next->locked = false; 195 218 }
Note:
See TracChangeset
for help on using the changeset viewer.