| 420 | } |
| 421 | |
| 422 | void concurrent_queue_base_v3::internal_pop( void* dst ) { |
| 423 | concurrent_queue_rep& r = *my_rep; |
| 424 | ticket k; |
| 425 | #if DO_ITT_NOTIFY |
| 426 | bool sync_prepare_done = false; |
| 427 | #endif |
| 428 | do { |
| 429 | k=r.head_counter++; |
| 430 | if ( (ptrdiff_t)(r.tail_counter-k)<=0 ) { // queue is empty |
| 431 | #if DO_ITT_NOTIFY |
| 432 | if( !sync_prepare_done ) { |
| 433 | ITT_NOTIFY( sync_prepare, dst ); |
| 434 | sync_prepare_done = true; |
| 435 | } |
| 436 | #endif |
| 437 | bool slept = false; |
| 438 | concurrent_monitor::thread_context thr_ctx; |
| 439 | r.items_avail.prepare_wait( thr_ctx, k ); |
| 440 | while( (ptrdiff_t)(r.tail_counter-k)<=0 ) { |
| 441 | __TBB_TRY { |
| 442 | slept = r.items_avail.commit_wait( thr_ctx ); |
| 443 | } __TBB_CATCH( tbb::user_abort& ) { |
| 444 | r.head_counter--; |
| 445 | __TBB_RETHROW(); |
| 446 | } __TBB_CATCH(...) { |
| 447 | __TBB_RETHROW(); |
| 448 | } |
| 449 | if (slept == true) break; |
| 450 | r.items_avail.prepare_wait( thr_ctx, k ); |
| 451 | } |
| 452 | if( !slept ) |
| 453 | r.items_avail.cancel_wait( thr_ctx ); |
| 454 | } |
| 455 | __TBB_ASSERT((ptrdiff_t)(r.tail_counter-k)>0, NULL); |
| 456 | } while( !r.choose(k).pop(dst,k,*this) ); |
| 457 | |
| 458 | // wake up a producer.. |
| 459 | r.slots_avail.notify( predicate_leq(k) ); |
| 460 | } |
| 461 | |
| 462 | void concurrent_queue_base_v3::internal_abort() { |
| 463 | concurrent_queue_rep& r = *my_rep; |
no test coverage detected