void fiber_scheduler_load_balance(fiber_scheduler_t* sched)
{
    fiber_scheduler_wsd_t* const scheduler = (fiber_scheduler_wsd_t*)sched;
    size_t max_steal = 50;
    size_t i = 2 * (scheduler->id + 1);
    const size_t end = i + 2 * (fiber_scheduler_num_threads - 1);
    const size_t mod = 2 * fiber_scheduler_num_threads;
    size_t local_count = wsd_work_stealing_deque_size(scheduler->schedule_from);
    for(; i < end; ++i) {
        const size_t index = i % mod;
        wsd_work_stealing_deque_t* const remote_queue = fiber_scheduler_thread_queues[index];
        assert(remote_queue != scheduler->queue_one);
        assert(remote_queue != scheduler->queue_two);
        if(!remote_queue) {
            continue;
        }
        size_t remote_count = wsd_work_stealing_deque_size(remote_queue);
        while(remote_count > local_count && max_steal > 0) {
            fiber_t* const stolen = (fiber_t*)wsd_work_stealing_deque_steal(remote_queue);
            if(stolen == WSD_EMPTY || stolen == WSD_ABORT) {
                ++scheduler->failed_steal_count;
                break;
            }
            wsd_work_stealing_deque_push_bottom(scheduler->schedule_from, stolen);
            --remote_count;
            ++local_count;
            --max_steal;
            ++scheduler->steal_count;
        }
    }
}
Beispiel #2
0
static int fiber_load_balance(fiber_manager_t* manager)
{
    size_t i = 2 * (manager->id + 1);
    const size_t end = i + 2 * (fiber_manager_num_threads - 1);
    const size_t mod = 2 * fiber_manager_num_threads;
    size_t local_count = wsd_work_stealing_deque_size(manager->schedule_from);
    for(; i < end; ++i) {
        const size_t index = i % mod;
        wsd_work_stealing_deque_t* const remote_queue = fiber_mananger_thread_queues[index];
        assert(remote_queue != manager->queue_one);
        assert(remote_queue != manager->queue_two);
        if(!remote_queue) {
            continue;
        }
        size_t remote_count = wsd_work_stealing_deque_size(remote_queue);
        while(remote_count > local_count) {
            fiber_t* const stolen = (fiber_t*)wsd_work_stealing_deque_steal(remote_queue);
            if(stolen == WSD_EMPTY || stolen == WSD_ABORT) {
                break;
            }
            assert(stolen->state == FIBER_STATE_READY);
            wsd_work_stealing_deque_push_bottom(manager->schedule_from, stolen);
            --remote_count;
            ++local_count;
        }
    }
    return 1;
}
Beispiel #3
0
void* run_func(void* p)
{
    intptr_t threadId = (intptr_t)p;
    while(!done) {
        void* ret = wsd_work_stealing_deque_steal(wsd_d2);
        if(ret != WSD_EMPTY && ret != WSD_ABORT) {
            __sync_add_and_fetch(&results[threadId][(intptr_t)ret], 1);
            __sync_add_and_fetch(&total, (intptr_t)ret);
            ++run_func_count[threadId];
        }
    }
    return NULL;
}