//! \~\file pithreadpoolloop.h
//! \~\ingroup Thread
//! \~\brief
//! \~english Parallel loop helper
//! \~russian Вспомогательный класс для параллельного цикла
/*
PIP - Platform Independent Primitives
Thread pool loop
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
*/
#ifndef PITHREADPOOLLOOP_H
#define PITHREADPOOLLOOP_H
#include "pisemaphore.h"
#include "pivector.h"
class PIThread;
//! \~\ingroup Thread
//! \~\brief
//! \~english Helper that runs one integer range across a fixed set of worker threads.
//! \~russian Вспомогательный класс, который выполняет один целочисленный диапазон на фиксированном наборе рабочих потоков.
class PIP_EXPORT PIThreadPoolLoop {
public:
//! \~english Constructs parallel loop runner with \a thread_cnt worker threads. If \a thread_cnt is less than or equal to zero, the
//! processor count is used.
//! \~russian Создает исполнитель параллельного цикла с \a thread_cnt рабочими потоками. Если \a thread_cnt меньше либо равен нулю,
//! используется количество процессоров.
PIThreadPoolLoop(int thread_cnt = -1);
//! \~english Stops worker threads and destroys the loop runner.
//! \~russian Останавливает рабочие потоки и уничтожает исполнитель цикла.
virtual ~PIThreadPoolLoop();
//! \~english Sets the iteration body called once for each index of a started range.
//! \~russian Устанавливает тело итерации, которое вызывается один раз для каждого индекса запущенного диапазона.
void setFunction(std::function f);
//! \~english Waits for the current in-flight batch started by \a start().
//! \~russian Ожидает завершения текущего запущенного пакета, начатого через \a start().
void wait();
//! \~english Starts asynchronous execution for indices in range [\a index_start, \a index_start + \a index_count).
//! \~russian Запускает асинхронное выполнение для индексов из диапазона [\a index_start, \a index_start + \a index_count).
void start(int index_start, int index_count);
//! \~english Runs the configured iteration body for indices in range [\a index_start, \a index_start + \a index_count) and waits for
//! completion.
//! \~russian Выполняет настроенное тело итерации для индексов из диапазона [\a index_start, \a index_start + \a index_count) и ожидает
//! завершения.
void exec(int index_start, int index_count);
//! \~english Sets iteration body to \a f, runs it for indices in range [\a index_start, \a index_start + \a index_count), and waits for
//! completion.
//! \~russian Устанавливает тело итерации \a f, выполняет его для индексов из диапазона [\a index_start, \a index_start + \a
//! index_count) и ожидает завершения.
void exec(int index_start, int index_count, std::function f);
private:
PIVector threads;
std::function func;
PISemaphore sem_exec, sem_done;
std::atomic_bool is_destroy = {false};
std::atomic_int counter = {0}, wait_count = {0};
};
#endif