Changeset 81ab5eb for libcfa/src/concurrency/channel.hfa
- Timestamp:
- Mar 29, 2026, 9:52:51 PM (5 days ago)
- Branches:
- master
- Children:
- e6e250d
- Parents:
- 00675ed4
- File:
-
- 1 edited
-
libcfa/src/concurrency/channel.hfa (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/channel.hfa
r00675ed4 r81ab5eb 117 117 printf("Channel %p Producer Blocks: %lu,\tProducer Ops: %lu,\t%.2f%% of Producer ops blocked\n", &c, c_blocks, c_ops, ((double)c_blocks)/c_ops * 100); 118 118 #endif 119 verifyf( __handle_waituntil_OR( cons ) || __handle_waituntil_OR( prods ) || isEmpty( cons ) && isEmpty( prods ),119 verifyf( __handle_waituntil_OR( cons ) || __handle_waituntil_OR( prods ) || empty( cons ) && empty( prods ), 120 120 "Attempted to delete channel with waiting threads (Deadlock).\n" ); 121 121 if ( size != 0 ) delete( buffer ); … … 123 123 size_t get_count( channel(T) & chan ) with(chan) { return __atomic_load_n( &count, __ATOMIC_RELAXED ); } 124 124 size_t get_size( channel(T) & chan ) with(chan) { return __atomic_load_n( &size, __ATOMIC_RELAXED ); } 125 bool has_waiters( channel(T) & chan ) with(chan) { return ! isEmpty( cons ) || ! isEmpty( prods ); }126 bool has_waiting_consumers( channel(T) & chan ) with(chan) { return ! isEmpty( cons ); }127 bool has_waiting_producers( channel(T) & chan ) with(chan) { return ! isEmpty( prods ); }125 bool has_waiters( channel(T) & chan ) with(chan) { return ! empty( cons ) || ! empty( prods ); } 126 bool has_waiting_consumers( channel(T) & chan ) with(chan) { return ! empty( cons ); } 127 bool has_waiting_producers( channel(T) & chan ) with(chan) { return ! empty( prods ); } 128 128 129 129 // closes the channel and notifies all blocked threads … … 164 164 void flush( channel(T) & chan, T elem ) with(chan) { 165 165 lock( mutex_lock ); 166 while ( count == 0 && ! isEmpty( cons ) ) {166 while ( count == 0 && ! empty( cons ) ) { 167 167 __cons_handoff( chan, elem ); 168 168 } … … 186 186 187 187 ConsEmpty: 188 if ( ! isEmpty( cons ) ) {188 if ( ! empty( cons ) ) { 189 189 if ( ! __handle_waituntil_OR( cons ) ) break ConsEmpty; 190 190 __cons_handoff( chan, elem ); … … 233 233 // buffer count must be zero if cons are blocked (also handles zero-size case) 234 234 ConsEmpty: 235 if ( ! isEmpty( cons ) ) {235 if ( ! empty( cons ) ) { 236 236 if ( ! __handle_waituntil_OR( cons ) ) break ConsEmpty; 237 237 __cons_handoff( chan, elem ); … … 261 261 count -= 1; 262 262 front = (front + 1) % size; 263 if (count == size - 1 && ! isEmpty( prods ) ) {263 if (count == size - 1 && ! empty( prods ) ) { 264 264 if ( ! __handle_waituntil_OR( prods ) ) return; 265 265 __buf_insert( chan, *(T *)first( prods ).extra ); // do waiting producer work … … 276 276 277 277 ZeroSize: 278 if ( size == 0 && ! isEmpty( prods ) ) {278 if ( size == 0 && ! empty( prods ) ) { 279 279 if ( ! __handle_waituntil_OR( prods ) ) break ZeroSize; 280 280 __prods_handoff( chan, retval ); … … 332 332 // have to check for the zero size channel case 333 333 ZeroSize: 334 if ( size == 0 && ! isEmpty( prods ) ) {334 if ( size == 0 && ! empty( prods ) ) { 335 335 if ( ! __handle_waituntil_OR( prods ) ) break ZeroSize; 336 336 __prods_handoff( chan, retval ); … … 384 384 // special case of __handle_waituntil_OR, that does some work to avoid starvation/deadlock case 385 385 bool __handle_pending( dlist( select_node ) & queue, select_node & mine ) { 386 while ( ! isEmpty( queue ) ) {386 while ( ! empty( queue ) ) { 387 387 // if node not a special OR case or if we win the special OR case race break 388 388 if ( ! first( queue ).clause_status || first( queue ).park_counter || __pending_set_other( first( queue ), mine, ((unsigned long int)(&(first( queue )))) ) ) … … 421 421 if ( ! node.park_counter ) { 422 422 // are we special case OR and front of cons is also special case OR 423 if ( ! unlikely(closed) && ! isEmpty( prods ) && first( prods ).clause_status && ! first( prods ).park_counter ) {423 if ( ! unlikely(closed) && ! empty( prods ) && first( prods ).clause_status && ! first( prods ).park_counter ) { 424 424 if ( ! __make_select_node_pending( node ) ) { 425 425 unlock( mutex_lock ); … … 437 437 } 438 438 // check if we can complete operation. If so race to establish winner in special OR case 439 if ( count != 0 || ! isEmpty( prods ) || unlikely(closed) ) {439 if ( count != 0 || ! empty( prods ) || unlikely(closed) ) { 440 440 if ( ! __make_select_node_available( node ) ) { // we didn't win the race so give up on registering 441 441 unlock( mutex_lock ); … … 453 453 // have to check for the zero size channel case 454 454 ZeroSize: 455 if ( size == 0 && ! isEmpty( prods ) ) {455 if ( size == 0 && ! empty( prods ) ) { 456 456 if ( ! __handle_waituntil_OR( prods ) ) break ZeroSize; 457 457 __prods_handoff( *chan, *ret ); … … 522 522 if ( ! node.park_counter ) { 523 523 // are we special case OR and front of cons is also special case OR 524 if ( ! unlikely(closed) && ! isEmpty( cons ) && first( cons ).clause_status && ! first( cons ).park_counter ) {524 if ( ! unlikely(closed) && ! empty( cons ) && first( cons ).clause_status && ! first( cons ).park_counter ) { 525 525 if ( ! __make_select_node_pending( node ) ) { 526 526 unlock( mutex_lock ); … … 537 537 } 538 538 // check if we can complete operation. If so race to establish winner in special OR case 539 if ( count != size || ! isEmpty( cons ) || unlikely(closed) ) {539 if ( count != size || ! empty( cons ) || unlikely(closed) ) { 540 540 if ( ! __make_select_node_available( node ) ) { // we didn't win the race so give up on registering 541 541 unlock( mutex_lock ); … … 554 554 // handle blocked consumer case via handoff (buffer is implicitly empty) 555 555 ConsEmpty: 556 if ( ! isEmpty( cons ) ) {556 if ( ! empty( cons ) ) { 557 557 if ( ! __handle_waituntil_OR( cons ) ) break ConsEmpty; 558 558 __cons_handoff( *chan, elem );
Note:
See TracChangeset
for help on using the changeset viewer.