MCPcopy Create free account
hub / github.com/cameron314/concurrentqueue / prepare_task_pool

Method prepare_task_pool

benchmarks/tbb/scheduler.cpp:425–463  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

423}
424
425size_t generic_scheduler::prepare_task_pool ( size_t num_tasks ) {
426 size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror
427 if ( T + num_tasks <= my_arena_slot->my_task_pool_size )
428 return T;
429 acquire_task_pool();
430 size_t H = __TBB_load_relaxed(my_arena_slot->head); // mirror
431 T -= H;
432 size_t new_size = T + num_tasks;
433 __TBB_ASSERT(!my_arena_slot->my_task_pool_size || my_arena_slot->my_task_pool_size >= min_task_pool_size, NULL);
434 if( !my_arena_slot->my_task_pool_size ) {
435 __TBB_ASSERT( !in_arena() && !my_arena_slot->task_pool_ptr, NULL );
436 if( new_size < min_task_pool_size ) new_size = min_task_pool_size;
437 my_arena_slot->allocate_task_pool( new_size );
438 }
439 // If the free space at the beginning of the task pool is too short, we
440 // are likely facing a pathological single-producer-multiple-consumers
441 // scenario, and thus it's better to expand the task pool
442 else if ( new_size <= my_arena_slot->my_task_pool_size - min_task_pool_size/4 ) {
443 // Relocate the busy part to the beginning of the deque
444 memmove( my_arena_slot->task_pool_ptr, my_arena_slot->task_pool_ptr + H, T * sizeof(task*) );
445 my_arena_slot->fill_with_canary_pattern( T, my_arena_slot->tail );
446 commit_relocated_tasks(T);
447 }
448 else {
449 // Grow task pool. As this operation is rare, and its cost is asymptotically
450 // amortizable, we can tolerate new task pool allocation done under the lock.
451 if ( new_size < 2 * my_arena_slot->my_task_pool_size )
452 new_size = 2 * my_arena_slot->my_task_pool_size;
453 task** old_pool = my_arena_slot->task_pool_ptr;
454 my_arena_slot->allocate_task_pool( new_size ); // updates my_task_pool_size
455 __TBB_ASSERT( T <= my_arena_slot->my_task_pool_size, "new task pool is too short" );
456 memcpy( my_arena_slot->task_pool_ptr, old_pool + H, T * sizeof(task*) );
457 commit_relocated_tasks(T);
458 __TBB_ASSERT( old_pool, "attempt to free NULL TaskPool" );
459 NFS_Free( old_pool );
460 }
461 assert_task_pool_valid();
462 return T;
463}
464
465/** ATTENTION:
466 This method is mostly the same as generic_scheduler::lock_task_pool(), with

Callers

nothing calls this directly

Calls 4

__TBB_load_relaxedFunction · 0.85
NFS_FreeFunction · 0.85
allocate_task_poolMethod · 0.80

Tested by

no test coverage detected