コード例 #1
0
ファイル: test_task_enqueue.cpp プロジェクト: jonarbo/GREASY
//! Regression test for a bug that caused premature arena destruction
void TestCascadedEnqueue () {
    REMARK("Testing cascaded enqueue\n");
	tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads() + 1);

    int minNumThreads = min(tbb::task_scheduler_init::default_num_threads(), MaxNumThreads) / 2;
	int maxNumThreads = min(tbb::task_scheduler_init::default_num_threads() * 2, MaxNumThreads);

	for ( int numThreads = minNumThreads; numThreads <= maxNumThreads; ++numThreads ) {
		for ( int i = 0; i < NumRepeats; ++i ) {
			CanStart = false;
            __TBB_Yield();
			NativeParallelFor( numThreads, EnqueuerBody() );
			CanStart = true;
            int j = 0;
			while ( j < numThreads ) {
                if ( Finished[j] )
                    ++j;
                else
    				__TBB_Yield();
			}
            for ( j = 0; j < numThreads; ++j )
                Finished[j] = false;
            REMARK("%02d threads; Iteration %03d\r", numThreads, i);
		}
	}
    REMARK( "                                 \r" );
}
コード例 #2
0
 static void apply( YourTable& table, int i ) {
     YourTable::accessor a1, a2;
     if(i&1) __TBB_Yield();
     table.insert( a1, MyKey::make(1) );
     __TBB_Yield();
     table.insert( a2, MyKey::make(1 + (1<<30)) ); // the same chain
     table.erase( a2 ); // if erase by key it would lead to deadlock for single thread
 }
コード例 #3
0
//Look for discussion of the issue at http://software.intel.com/en-us/forums/showthread.php?t=102159
void TestEnqueueOrder () {
    REMARK("Testing order of enqueued tasks\n");
    tbb::task_scheduler_init init(1); // to simplify transition checks only one extra worker for enqueue
    g_order = tbb::priority_low;
    g_order_established = false;
    for( int i = 0; i < 1000; i++)
        OrderedTask::start(i);
    while( g_order == tbb::priority_low ) __TBB_Yield();
    while( g_order != tbb::priority_low ) __TBB_Yield();
}
コード例 #4
0
 void operator() () const {
     Harness::ConcurrencyTracker ct;
     AssertLive();
     if ( g_Throw ) {
         if ( ++m_TaskCount == SKIP_CHORES )
             __TBB_THROW( test_exception(EXCEPTION_DESCR1) );
         __TBB_Yield();
     }
     else {
         ++g_TaskCount;
         while( !Concurrency::is_current_task_group_canceling() )
             __TBB_Yield();
     }
 }
コード例 #5
0
 void operator () () const {
     if ( m_pOwner->m_sharingMode & ParallelWait ) {
         while ( Harness::ConcurrencyTracker::PeakParallelism() < m_pOwner->m_numThreads )
             __TBB_Yield();
     }
     ++s_tasksExecuted;
 }
コード例 #6
0
ファイル: test_rml_mixed.cpp プロジェクト: cran/RcppParallel
void TBBWork() {
    if( AvailWork>=0 ) {
        int k = --AvailWork;
        if( k==-1 ) {
            TBB_RunTime.server->adjust_job_count_estimate(-(TBB_MaxThread-1));
            ++CompletionCount;
        } else if( k>=0 ) {
            for( int k=0; k<4; ++k ) {
                OMP_Team team( *OMP_RunTime.server );
                int n = OMP_RunTime.server->try_increase_load( OMP_ParallelRegionSize-1, /*strict=*/false );
                team.barrier = 0;
                ::rml::job* array[OMP_ParallelRegionSize-1];
                if( n>0)
                    OMP_RunTime.server->get_threads( n, &team, array );
                // Master does work inside parallel region too.
                OMPWork();
                // Master waits for workers to finish
                if( n>0 )
                    while( team.barrier!=unsigned(n) ) {
                        __TBB_Yield();
                    } 
            }
            ++CompletionCount;
        }
    }
}
コード例 #7
0
    void Run ( uint_t idx ) {
#if TBBTEST_USE_TBB
        tbb::task_scheduler_init init;
#endif
        AssertLive();
        if ( idx == 0 ) {
            ASSERT ( !m_taskGroup && !m_tasksSpawned, "SharedGroupBody must be reset before reuse");
            m_taskGroup = new Concurrency::task_group;
            Spawn( c_numTasks0 );
            Wait();
            if ( m_sharingMode & VagabondGroup )
                m_barrier.wait();
            else
                DeleteTaskGroup();
        }
        else {
            while ( m_tasksSpawned == 0 )
                __TBB_Yield();
            ASSERT ( m_taskGroup, "Task group is not initialized");
            Spawn (c_numTasks1);
            if ( m_sharingMode & ParallelWait )
                Wait();
            if ( m_sharingMode & VagabondGroup ) {
                ASSERT ( idx == 1, "In vagabond mode SharedGroupBody must be used with 2 threads only" );
                m_barrier.wait();
                DeleteTaskGroup();
            }
        }
        AssertLive();
    }
コード例 #8
0
void task_scheduler_observer_v3::observe( bool state ) {
    if( state ) {
        if( !my_proxy ) {
            if( !__TBB_InitOnce::initialization_done() )
                DoOneTimeInitializations();
            my_busy_count = 0;
            my_proxy = new observer_proxy(*this);
            if( generic_scheduler* s = governor::local_scheduler_if_initialized() ) {
                // Notify newly created observer of its own thread.
                // Any other pending observers are notified too.
                s->notify_entry_observers();
            }
        } 
    } else {
        if( observer_proxy* proxy = my_proxy ) {
            my_proxy = NULL;
            __TBB_ASSERT( proxy->gc_ref_count>=1, "reference for observer missing" );
            {
                task_scheduler_observer_mutex_scoped_lock lock(the_task_scheduler_observer_mutex.begin()[0],/*is_writer=*/true);
                proxy->observer = NULL;
            }
            proxy->remove_ref_slow();
            while( my_busy_count ) {
                __TBB_Yield();
            }
        }
    }
}
コード例 #9
0
 void operator()( int ) const {
     for( int i=0; i<my_m; ++i ) {
         // Busy wait to synchronize threads
         int j = 0;
         while( Counter<i ) {
             if( ++j==1000000 ) {
                 // If Counter<i after a million iterations, then we almost surely have
                 // more logical threads than physical threads, and should yield in
                 // order to let suspended logical threads make progress.
                 j = 0;
                 __TBB_Yield();
             }
         }
         // Now all threads attempt to simultaneously insert a key.
         int k;
         {
             MyTable::accessor a;
             MyKey key = MyKey::make(i);
             if( my_table.insert( a, key ) )
                 a->second.set_value( 1 );
             else
                 a->second.set_value( a->second.value_of()+1 );
             k = a->second.value_of();
         }
         if( k==my_nthread )
             Counter=i+1;
     }
 }
コード例 #10
0
ファイル: observer_proxy.cpp プロジェクト: xiangyuan/Unreal4
void observer_list::clear () {
    __TBB_ASSERT( this != &the_global_observer_list, "Method clear() cannot be used on the list of global observers" );
    // Though the method will work fine for the empty list, we require the caller
    // to check for the list emptiness before invoking it to avoid extra overhead.
    __TBB_ASSERT( !empty(), NULL );
    {
        scoped_lock lock(mutex(), /*is_writer=*/true);
        observer_proxy *next = my_head;
        while ( observer_proxy *p = next ) {
            __TBB_ASSERT( p->my_version >= 6, NULL );
            next = p->my_next;
            // Both proxy p and observer p->my_observer (if non-null) are guaranteed
            // to be alive while the list is locked.
            task_scheduler_observer_v3 *obs = p->my_observer;
            // Make sure that possible concurrent observer destruction does not
            // conflict with the proxy list cleanup.
            if ( !obs || !(p = (observer_proxy*)__TBB_FetchAndStoreW(&obs->my_proxy, 0)) )
                continue;
            __TBB_ASSERT( !next || p == next->my_prev, NULL );
            __TBB_ASSERT( is_alive(p->my_ref_count), "Observer's proxy died prematurely" );
            __TBB_ASSERT( p->my_ref_count == 1, "Reference for observer is missing" );
            __TBB_ASSERT( !obs->my_busy_count, "Local observer in an empty arena cannot be marked as busy" );
            store<relaxed>( obs->my_busy_count, interface6::task_scheduler_observer::v6_trait );
#if TBB_USE_ASSERT
            p->my_observer = NULL;
            p->my_ref_count = 0;
#endif /* TBB_USE_ASSERT */
            remove(p);
            delete p;
        }
    }
    while( my_head )
        __TBB_Yield();
}
コード例 #11
0
 server_thread& wait_for_thread() const {
     for(;;) {
         server_thread* ptr=const_cast<server_thread*volatile&>(my_thread);
         if( ptr ) 
             return *ptr;
         __TBB_Yield();
     } 
 }
コード例 #12
0
/** An interval is the code between two operations on the job_automaton that we are testing. */
void Cover( int k ) {
    ASSERT( k<N, NULL );
    ++Coverage[k];
    if( DelayMask>>k&1 ) {
        // Introduce delay (and possibly a thread context switch)
        __TBB_Yield();
    }
}
コード例 #13
0
ファイル: market.cpp プロジェクト: AlessioVallero/RaspberryPI
void market::wait_workers () {
    // usable for this kind of scheduler only
    __TBB_ASSERT(governor::needsWaitWorkers(), NULL);
    // wait till terminating last worker decresed my_ref_count
    while (__TBB_load_with_acquire(my_ref_count) > 1)
        __TBB_Yield();
    __TBB_ASSERT(1 == my_ref_count, NULL);
    release();
}
コード例 #14
0
// Tests task_group_context state propagation, also for cancellation.
void TestSetPriority() {
    REMARK("Testing set_priority() with existing forest\n");
    const int workers = last*2+1; // +1 is worker thread executing the first task
    tbb::task_scheduler_init init(workers+1); // +1 is master thread
    g_barrier = workers;
    is_finished = false;
    tbb::task::spawn(*new(tbb::task::allocate_root()) TestSetPriorityTask(0,0));
    while(g_barrier) __TBB_Yield();
    g_trees[0][2]->set_priority(tbb::priority_high);
    g_trees[0][4]->set_priority(tbb::priority_normal);
    g_trees[1][3]->set_priority(tbb::priority_high); // Regression test: it must not set priority_high to g_trees[0][4]
    //                                         -  1  2  3  4  5  6  7
    const int expected_priority[2][last+1] = {{0, 0, 1, 0, 0, 1, 0, 0},
                                              {0, 0, 0, 1, 0, 0, 1, 1}};
    for (int t = 0; t < 2; ++t)
        for (int i = first; i <= last; ++i) {
            REMARK("\r                    \rTask %i... ", i);
            ASSERT(g_trees[t][i]->priority() == expected_priority[t][i]? tbb::priority_high : tbb::priority_normal, NULL);
            REMARK("OK");
        }
    REMARK("\r                    \r");
    REMARK("Also testing cancel_group_execution()\n"); // cancellation shares propagation logic with set_priority() but there are also differences
    g_trees[0][4]->cancel_group_execution();
    g_trees[0][5]->cancel_group_execution();
    g_trees[1][3]->cancel_group_execution();
    //                                             -  1  2  3  4  5  6  7
    const int expected_cancellation[2][last+1] = {{0, 0, 0, 0, 1, 1, 0, 0},
                                                  {0, 0, 0, 1, 0, 0, 1, 1}};
    for (int t = 0; t < 2; ++t)
        for (int i = first; i <= last; ++i) {
            REMARK("\r                    \rTask %i... ", i);
            ASSERT( g_trees[t][i]->is_group_execution_cancelled() == (expected_cancellation[t][i]==1), NULL);
            REMARK("OK");
        }
    REMARK("\r                    \r");
    g_barrier = workers;
    is_finished = true;
    REMARK("waiting tasks to terminate\n");
    while(g_barrier) __TBB_Yield();
    for (int t = 0; t < 2; ++t)
        for (int i = first; i <= last; ++i)
            delete g_trees[t][i];
}
コード例 #15
0
void State::exercise( bool is_owner ) {
    barrier.wait();
    if( is_owner ) {
        Cover(0);
        if( ja.try_acquire() ) {
            Cover(1);
            ++job_created; 
            ja.set_and_release(job);
            Cover(2);
            if( ja.try_acquire() ) {
                Cover(3);
                ja.release();
                Cover(4);
                if( ja.try_acquire() ) {
                    Cover(5);
                    ja.release();
                }
            }
            Cover(6);
        } else {
            Cover(7);
        }
        if( DelayMask&1<<N ) {
            while( !job_received ) 
                __TBB_Yield();
        }
    } else {
        // Using extra bit of DelayMask for choosing whether to run wait_for_job or not.
        if( DelayMask&1<<N ) {
            rml::job* j= &ja.wait_for_job(); 
            if( j!=&job ) REPORT("%p\n",j);
            ASSERT( j==&job, NULL );
            job_received = true;
        }
        Cover(8);
    }   
    rml::job* j;
    if( ja.try_plug(j) ) {
        ASSERT( j==&job || !j, NULL );
        if( j ) {
            Cover(9+is_owner);
            ++job_destroyed;
        } else {
            __TBB_ASSERT( !is_owner, "owner failed to create job but plugged self" );
            Cover(11);
        } 
    } else {
        Cover(12+is_owner);
    }
}
コード例 #16
0
    void RunTaskForest ( int id ) const {
        ASSERT( id < g_NumMasters, NULL );
        g_LeavesExecuted[id] = 0;
        int d = BaseDepth + id;
        tbb::task_scheduler_init init(P-1);
        tbb::task_group_context ctx (tbb::task_group_context::isolated);
        tbb::empty_task &r = *new( tbb::task::allocate_root(ctx) ) tbb::empty_task;
        const int R = 4;
        r.set_ref_count( R * P + 1 );
        // Only PreemptionActivator thread changes its task tree priority in preemption test mode
        const uintptr_t opts = (id == PreemptionActivatorId) ? m_opts : (m_opts & ~(uintptr_t)TestPreemption);
        for ( int i = 0; i < R; ++i ) {
            for ( int j = 1; j < P; ++j )
                r.spawn( *new(r.allocate_child()) NodeType(id, MinBaseDepth + id, opts, &r) );
            r.spawn( *new(r.allocate_child()) NodeType(id, d, opts, &r) );
        }
        int count = 1;
        intptr_t lastExecuted = 0;
        while ( r.ref_count() > 1 ) {
            // Give workers time to make some progress.
            for ( int i = 0; i < 10 * count; ++i )
                __TBB_Yield();
#if __TBB_TASK_PRIORITY
            if ( lastExecuted == g_LeavesExecuted[id] ) {
                // No progress. Likely all workers left to higher priority arena,
                // and then returned to RML. Request workers back from RML.
                tbb::task::enqueue( *new(tbb::task::allocate_root() ) tbb::empty_task, id == 0 ? Low : High );
                Harness::Sleep(count);
#if __TBB_ipf
                // Increased sleep periods are required on systems with unfair hyperthreading (Itanium(R) 2 processor)
                count += 10;
#endif
            }
            else {
                count = 1;
                lastExecuted = g_LeavesExecuted[id];
            }
#else /* !__TBB_TASK_PRIORITY */
            (void)lastExecuted;
            tbb::task::enqueue( *new(tbb::task::allocate_root() ) tbb::empty_task );
#endif /* !__TBB_TASK_PRIORITY */
        }
        ASSERT( g_LeavesExecuted[id] == R * ((1 << d) + ((P - 1) * (1 << (MinBaseDepth + id)))), NULL );
        g_LeavesExecuted[id] = -1;
        tbb::task::destroy(r);
    }
コード例 #17
0
 void operator()( long k ) const {
     tbb::tick_count t0 = tbb::tick_count::now();
     for( long i=0; i<10000; ++i ) {
         // Wait for previous thread to notify us 
         for( int j=0; CyclicCounter!=k && !Quit; ++j ) {
             __TBB_Yield();
             if( j%100==0 ) {
                 tbb::tick_count t1 = tbb::tick_count::now();
                 if( (t1-t0).seconds()>=1.0*number_of_threads ) {
                     REPORT("Warning: __TBB_Yield failing to yield with %d threads (or system is heavily loaded)\n",number_of_threads);
                     Quit = true;
                     return;
                 }
             }
         }
         // Notify next thread that it can run            
         CyclicCounter = (k+1)%number_of_threads;
     }
 }
コード例 #18
0
 void operator()( int k ) const {
     if( k==0 ) {
         int number_of_pops = nthread-1;
         // Wait for all pops to pend.
         while( queue.size()>-number_of_pops ) {
             __TBB_Yield();
         }
         for( int i=0; ; ++i ) {
             ASSERT( queue.size()==i-number_of_pops, NULL );
             ASSERT( queue.empty()==(queue.size()<=0), NULL );
             if( i==number_of_pops ) break;
             // Satisfy another pop
             queue.push( T() );
         }
     } else {
         // Pop item from queue
         T item;
         queue.pop(item);
     }
 }
コード例 #19
0
 void Wait () {
     while ( m_threadsReady != m_numThreads )
         __TBB_Yield();
     const uint_t numSpawned = c_numTasks0 + c_numTasks1 * (m_numThreads - 1);
     ASSERT ( m_tasksSpawned == numSpawned, "Wrong number of spawned tasks. The test is broken" );
     REMARK("Max spawning parallelism is %u out of %u\n", Harness::ConcurrencyTracker::PeakParallelism(), g_MaxConcurrency);
     if ( m_sharingMode & ParallelWait ) {
         m_barrier.wait( &Harness::ConcurrencyTracker::Reset );
         {
             Harness::ConcurrencyTracker ct;
             m_taskGroup->wait();
         }
         if ( Harness::ConcurrencyTracker::PeakParallelism() == 1 )
             REPORT ( "Warning: No parallel waiting detected in TestParallelWait\n" );
         m_barrier.wait();
     }
     else
         m_taskGroup->wait();
     ASSERT ( m_tasksSpawned == numSpawned, "No tasks should be spawned after wait starts. The test is broken" );
     ASSERT ( s_tasksExecuted == numSpawned, "Not all spawned tasks were executed" );
 }
コード例 #20
0
    void SpawnChildren ( task* parent_node ) {
        ASSERT( m_depth > 0, NULL );
        if ( g_LeavesExecuted[m_tid] % (100 / m_depth) == 0 ) {
            if ( m_opts & Flog ) {
#if __TBB_TASK_PRIORITY
                task *r = m_opts & FlogEncloser ? this : m_root;
                tbb::priority_t p = r->group_priority();
                r->set_group_priority( p == Low ? High : Low );
#endif /* __TBB_TASK_PRIORITY */
            }
            else
                __TBB_Yield();
        }
        parent_node->set_ref_count(NumLeafTasks + 1);
        --m_depth;
        for ( int i = 0; i < NumLeafTasks; ++i ) {
            task *t = m_depth ? (task*) new(parent_node->allocate_child()) NodeType(m_tid, m_depth, m_opts, m_root) 
                              : (task*) new(parent_node->allocate_child()) LeafTask(m_tid, m_opts);
            task::spawn(*t);
        }
    }
コード例 #21
0
 tbb::task* execute() {
     if( !m_i ) { // the first task creates two trees
         g_default_ctx = group();
         for( int i = 0; i <= 1; ++i ) {
             g_trees[i][1] = new tbb::task_group_context( tbb::task_group_context::isolated );
             tbb::task::spawn(*new(tbb::task::allocate_root(*g_trees[i][1])) TestSetPriorityTask(i, 1));
         }
     }
     else if( m_i <= last/2 ) { // is divisible
         for( int i = 0; i <= 1; ++i ) {
             const int index = 2*m_i + i;
             g_trees[m_tree][index] = new tbb::task_group_context ( tbb::task_group_context::bound );
             tbb::task::spawn(*new(tbb::task::allocate_root(*g_trees[m_tree][index])) TestSetPriorityTask(m_tree, index));
         }
     }
     --g_barrier;
     //REMARK("Task %i executing\n", m_i);
     while (!is_finished) __TBB_Yield();
     change_group(*g_default_ctx); // avoid races with destruction of custom contexts
     --g_barrier;
     return NULL;
 }
コード例 #22
0
 void operator()( int i ) const {
     theLocalState->m_isMaster = true;
     uintptr_t f = i <= MaxFlagIndex ? 1<<i : 0;
     MyObserver o(f);
     if ( theTestMode & tmSynchronized )
         theMasterBarrier.wait();
     // when mode is local observation but not synchronized and when num threads == default
     if ( theTestMode & tmAutoinitialization )
         o.observe(true); // test autoinitialization can be done by observer
     // when mode is local synchronized observation and when num threads == default
     if ( theTestMode & tmLeavingControl )
         o.test_leaving();
     // Observer in enabled state must outlive the scheduler to ensure that
     // all exit notifications are called.
     tbb::task_scheduler_init init(m_numThreads);
     // when local & non-autoinitialized observation mode
     if ( theTestMode & tmLocalObservation )
         o.observe(true);
     for ( int j = 0; j < 2; ++j ) {
         tbb::task &t = *new( tbb::task::allocate_root() ) FibTask(m_numThreads, f, o);
         tbb::task::spawn_root_and_wait(t);
         thePrevMode = theTestMode;
     }
     if( o.is_leaving_test() ) {
         REMARK( "Testing on_scheduler_leaving()\n");
         ASSERT(o.m_workerEntries > 0, "Unbelievable");
         // TODO: start from 0?
         for ( int j = o.m_workerExits; j < o.m_workerEntries; j++ ) {
             REMARK( "Round %d: entries %d, exits %d\n", j, (int)o.m_workerEntries, (int)o.m_workerExits );
             ASSERT_WARNING(o.m_workerExits == j, "Workers unexpectedly leaved arena");
             o.dismiss_one();
             double n_seconds = 5;
             (Harness::TimedWaitWhileEq(n_seconds))(o.m_workerExits, j);
             ASSERT( n_seconds >= 0, "Time out while waiting for a worker to leave arena");
             __TBB_Yield();
         }
     }
 }
コード例 #23
0
ファイル: market.cpp プロジェクト: Havoc/mangos-boost
void market::process( job& j ) {
    generic_scheduler& s = static_cast<generic_scheduler&>(j);
    arena *a = NULL;
    __TBB_ASSERT( governor::is_set(&s), NULL );
#if !__TBB_SLEEP_PERMISSION
    while ( (a = arena_in_need(a)) )
        a->process(s);
#else//__TBB_SLEEP_PERMISSION
    enum {
        query_interval = 1000,
        first_interval = 1,
        pause_time = 100 // similar to PauseTime used for the stealing loop
    };
    for(int i = first_interval; ; i--) {
        while ( (a = arena_in_need(a)) )
        {
            a->process(s);
            i = first_interval;
        }
        if( i == 0 ) {
#if __TBB_TASK_PRIORITY
            arena_list_type &al = my_priority_levels[my_global_top_priority].arenas;
#else /* __TBB_TASK_PRIORITY */
            arena_list_type &al = my_arenas;
#endif /* __TBB_TASK_PRIORITY */
            if( al.empty() ) // races if any are innocent TODO: replace by an RML query interface
                break; // no arenas left, perhaps going to shut down
            if( the_global_observer_list.ask_permission_to_leave() )
                break; // go sleep
            __TBB_Yield();
            i = query_interval;
        } else __TBB_Pause(pause_time);
    }
#endif//__TBB_SLEEP_PERMISSION
    GATHER_STATISTIC( ++s.my_counters.market_roundtrips );
}
コード例 #24
0
ファイル: test_task_enqueue.cpp プロジェクト: jonarbo/GREASY
void TimedYield( double pause_time ) {
    tbb::tick_count start = tbb::tick_count::now();
    while( (tbb::tick_count::now()-start).seconds() < pause_time )
        __TBB_Yield();
}
コード例 #25
0
ファイル: test_eh_tasks.cpp プロジェクト: cran/RcppParallel
inline void WaitForException () {
    int n = 0;
    while ( ++n < c_Timeout && !__TBB_load_with_acquire(g_ExceptionCaught) )
        __TBB_Yield();
    ASSERT_WARNING( n < c_Timeout, "WaitForException failed" );
}
コード例 #26
0
ファイル: private_server.cpp プロジェクト: ekzobam/HGCore
 /*override*/ void yield() {__TBB_Yield();}
コード例 #27
0
ファイル: test_rml_omp.cpp プロジェクト: LucaMarradi/dealii
void FireUpJobs( MyServer& server, MyClient& client, int max_thread, int n_extra, Checker* checker ) {
    ASSERT( max_thread>=0, NULL );
#if _WIN32||_WIN64
    ::rml::server::execution_resource_t me;
    server.register_master( me );
#endif /* _WIN32||_WIN64 */
    client.server = &server;
    MyTeam team(server,size_t(max_thread));
    MyServer::size_type n_thread = 0;
    for( int iteration=0; iteration<4; ++iteration ) {
        for( size_t i=0; i<team.max_thread; ++i )
            team.info[i].ran = false;
        switch( iteration ) {
            default:
                n_thread = int(max_thread);
                break;
            case 1:
                // No change in number of threads
                break;
            case 2:
                // Decrease number of threads.
                n_thread = int(max_thread)/2;
                break;
            // Case 3 is same code as the default, but has effect of increasing the number of threads.
        }
        team.barrier = 0;
        REMARK("client %d: server.run with n_thread=%d\n", client.client_id(), int(n_thread) );
        server.independent_thread_number_changed( n_extra );
        if( checker ) {
            // Give RML time to respond to change in number of threads.
            Harness::Sleep(1);
        }
        int n_delivered = server.try_increase_load( n_thread, StrictTeam );
        ASSERT( !StrictTeam || n_delivered==int(n_thread), "server failed to satisfy strict request" );
        if( n_delivered<0 ) {
            REMARK( "client %d: oversubscription occurred (by %d)\n", client.client_id(), -n_delivered );
            server.independent_thread_number_changed( -n_extra );
            n_delivered = 0;
        } else {
            team.n_thread = n_delivered;
            ::rml::job* job_array[JobArraySize];
            job_array[n_delivered] = (::rml::job*)intptr_t(-1);
            server.get_threads( n_delivered, &team, job_array );
            __TBB_ASSERT( job_array[n_delivered]== (::rml::job*)intptr_t(-1), NULL );
            for( int i=0; i<n_delivered; ++i ) {
                MyJob* j = static_cast<MyJob*>(job_array[i]);
                int s = j->state;
                ASSERT( s==MyJob::idle||s==MyJob::busy, NULL );
            }
            server.independent_thread_number_changed( -n_extra );
            REMARK("client %d: team size is %d\n", client.client_id(), n_delivered);
            if( checker ) {
                checker->check_number_of_threads_delivered( n_delivered, n_thread, n_extra );
            }
            // Protocol requires that master wait until workers have called "done_processing"
            while( team.barrier!=n_delivered ) {
                ASSERT( team.barrier>=0, NULL );
                ASSERT( team.barrier<=n_delivered, NULL );
                __TBB_Yield();
            }
            REMARK("client %d: team completed\n", client.client_id() );
            for( int i=0; i<n_delivered; ++i ) {
                ASSERT( team.info[i].ran, "thread on team allegedly delivered, but did not run?" );
            }
        }
        for( MyServer::size_type i=n_delivered; i<MyServer::size_type(max_thread); ++i ) {
            ASSERT( !team.info[i].ran, "thread on team ran with illegal index" );
        }
    }
#if _WIN32||_WIN64
    server.unregister_master( me );
#endif
}
コード例 #28
0
ファイル: test_task_enqueue.cpp プロジェクト: jonarbo/GREASY
	void Execute() {
		while ( !CanStart )
		    __TBB_Yield();
		tbb::task::enqueue( *new( tbb::task::allocate_root() ) CarrierTask(m_taskToSpawn) );
	}
コード例 #29
0
void EmulateWork( int ) {
    for ( int i = 0; i < 1000; ++i )
        __TBB_Yield();
}
コード例 #30
0
ファイル: tbb_thread.cpp プロジェクト: klueska/tbb-parlib
void thread_yield_v3()
{
    __TBB_Yield();
}