21 #ifndef _TBB_task_stream_H 22 #define _TBB_task_stream_H 39 template<
typename T,
typename mutex_t >
51 const population_t
one = 1;
55 __TBB_ASSERT( pos<
int(
sizeof(population_t)*CHAR_BIT), NULL );
61 __TBB_ASSERT( pos<
int(
sizeof(population_t)*CHAR_BIT), NULL );
67 __TBB_ASSERT( pos<
int(
sizeof(population_t)*CHAR_BIT), NULL );
68 return (val & (one<<pos)) != 0;
75 population_t population[Levels];
81 for(
int level = 0; level < Levels; level++) {
82 population[level] = 0;
88 const unsigned max_lanes =
sizeof(
population_t) * CHAR_BIT;
90 N = n_lanes>=max_lanes ? max_lanes : n_lanes>2 ? 1<<(
__TBB_Log2(n_lanes-1)+1) : 2;
91 __TBB_ASSERT( N==max_lanes || N>=n_lanes && ((N-1)&N)==0,
"number of lanes miscalculated");
92 __TBB_ASSERT( N <=
sizeof(population_t) * CHAR_BIT, NULL );
93 for(
int level = 0; level < Levels; level++) {
100 for(
int level = 0; level < Levels; level++)
101 if (lanes[level])
delete[] lanes[level];
109 idx = random.
get() & (N-1);
111 if( lock.
try_acquire(lanes[level][idx].my_mutex) ) {
112 lanes[level][idx].my_queue.push_back(source);
120 task*
pop(
int level,
unsigned& last_used_lane ) {
123 unsigned idx = (last_used_lane+1)&(N-1);
124 for( ; population[level]; idx=(idx+1)&(N-1) ) {
126 lane_t& lane = lanes[level][idx];
137 last_used_lane = idx;
143 return !population[level];
151 for(
int level = 0; level < Levels; level++)
152 for(
unsigned i=0; i<N; ++i) {
153 lane_t& lane = lanes[level][i];
155 for(lane_t::queue_base_t::iterator it=lane.
my_queue.begin();
156 it!=lane.
my_queue.end(); ++it, ++result)
160 tbb::task::destroy(*t);
unsigned short get()
Get a random number.
void push(task *source, int level, FastRandom &random)
Push a task into a lane.
void set_one_bit(population_t &dest, int pos)
task * pop(int level, unsigned &last_used_lane)
Try finding and popping a task.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
void initialize(unsigned n_lanes)
bool empty(int level)
Checks existence of a task.
Represents acquisition of a mutex.
The container for "fairness-oriented" aka "enqueued" tasks.
void __TBB_AtomicAND(volatile void *operand, uintptr_t addend)
intptr_t drain()
Destroys all remaining tasks in every lane. Returns the number of destroyed tasks.
bool try_acquire(spin_mutex &m)
Try acquiring lock (non-blocking)
intptr_t __TBB_Log2(uintptr_t x)
bool is_bit_set(population_t val, int pos)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void * lock
void clear_one_bit(population_t &dest, int pos)
queue_and_mutex< task *, spin_mutex > lane_t
std::deque< T, tbb_allocator< T > > queue_base_t
Pads type T to fill out to a multiple of cache line size.
Base class for user-defined tasks.
Essentially, this is just a pair of a queue and a mutex to protect the queue.
Base class for types that should not be copied or assigned.
void __TBB_AtomicOR(volatile void *operand, uintptr_t addend)
A fast random number generator.