#include "static_scheduler.hpp"

#include <boost/thread.hpp>

namespace {

struct StaticArgs {
    int tid;
    int F;
    int K;
    task_fn_t task;
    void* ctx;
    bool affinity;
};

void worker(StaticArgs a) {
    if (a.affinity)
        set_thread_affinity(a.tid);

    int base = a.F / a.K;
    int rem  = a.F % a.K;

    int start = a.tid * base;
    int end   = start + base;
    if (a.tid == a.K - 1)
        end += rem;

    for (int f = start; f < end; ++f)
        a.task(f, a.tid, a.K, a.ctx);
}

} // namespace

int run_static_scheduler(int F, int K, task_fn_t task, void* ctx, bool affinity)
{
    if (F <= 0 || K <= 0 || task == nullptr)
        return -1;

    boost::thread_group workers;
    for (int tid = 0; tid < K; ++tid) {
        StaticArgs a{tid, F, K, task, ctx, affinity};
        workers.create_thread(boost::bind(worker, a));
    }
    workers.join_all();
    return 0;
}
