OSTHREAD_FUNC test10_testThread(void *parm){ TaskInfo *ti; TaskScheduler *ts = tgetTaskScheduler(); ti = ts->createTask(test10_PROGTest, 0); assert(ti); ts->run(); return (void*)-1; }
OSTHREAD_FUNC test10_incThread(void *parm){ TaskInfo *ti; TaskScheduler *ts = tgetTaskScheduler(); ti = ts->createTask(test10_PROGIncrement, 0); ts->assignFixedTask(1, ti); test10_event.set(); ts->run(); return (void*)-1; }
void parfor(std::size_t idx_start, std::size_t idx_end, Lambda &&loopBody, TaskScheduler &scheduler, std::size_t blockSize = 32) { static_assert(std::is_same<void, typename std::result_of<Lambda(std::size_t)>::type>::value, "Loop body must return void"); auto loopLen = (idx_end - idx_start); //Execute short loops in serial if(loopLen < 10*blockSize) { for(std::size_t i=idx_start; i<idx_end; ++i) { loopBody(i); } return; } auto full_blocks = loopLen / blockSize; auto cleanup_start = full_blocks * blockSize + idx_start; auto Nblocks = full_blocks + ((cleanup_start < idx_end) ? 1 : 0); std::vector<std::future<void>> futs; futs.reserve(Nblocks); for (std::size_t iblock = 0; iblock < Nblocks; ++iblock) { std::size_t i_start = idx_start + iblock * blockSize; std::size_t i_end = i_start + blockSize; i_end = (i_end < idx_end) ? i_end : idx_end; auto [task, fut] = scheduler.createTask([&loopBody, i_start, i_end]() { for (auto i = i_start; i < i_end; ++i) { loopBody(i); } }); scheduler.enqueue(task); futs.push_back(std::move(fut)); } wait_all(futs); //return futs; }