//Test using simple atomic addition, stops when the task queue is empty bool atomicAddTest() { long long numValues = 1000; atomicSum = 0; //The tasks containing numbers to be added std::vector<std::shared_ptr<AtomicAddTask>> addTasks(numValues); for (auto i = 0; i < addTasks.size(); i++) { addTasks[i] = std::make_shared<AtomicAddTask>(); addTasks[i]->number = (i + 1); } ems::ThreadPool pool; for (auto &addTask : addTasks) pool.addTask(addTask); pool.addTaskHandler<AtomicAddTask>(atomicAddTaskHandler); //Perform the sum pool.handleTasks(4, true); //Join the threads pool.join(); //Check that no exception occured if (pool.getThreadException()) return false; //Check the sum if (atomicSum != ((numValues*(numValues + 1)) / 2)) return false; return true; }
/** * \brief Retrieve the task list */ void TaskMainWindow::retrieveTasklist() { std::set<long> taskids; addids(taskids, taskqueue, Astro::TASK_PENDING); addids(taskids, taskqueue, Astro::TASK_EXECUTING); addids(taskids, taskqueue, Astro::TASK_FAILED); addids(taskids, taskqueue, Astro::TASK_CANCELLED); addids(taskids, taskqueue, Astro::TASK_COMPLETED); // now add all tasks in the set to the task list addTasks(taskids); }
//Test using additive parallel reduction, main threads adds new tasks to the queue until the top level is reached bool parallelAddTest() { //Must be power of two long long numValues = 1024; //The tasks containing numbers to be added std::vector<std::shared_ptr<ParallelAddTask>> addTasks(numValues); long long numLevels = 0; long long levelSize = numValues; while (levelSize >>= 1) ++numLevels; for (long long i = 0; i < numValues/2; i++) { addTasks[i] = std::make_shared<ParallelAddTask>(); addTasks[i]->number[0] = (i + 1); addTasks[i]->number[1] = numValues/2 + (i + 1); addTasks[i]->level = 0; } ems::ThreadPool pool; for (auto &addTask : addTasks) pool.addTask(addTask); pool.addTaskHandler<ParallelAddTask>(parallelAddTaskHandler); //Perform the sum pool.handleTasks(4, false); long long parallelSum = 0; //Used to store completed tasks std::vector<std::shared_ptr<ParallelAddTask>> storedTasks(numLevels, nullptr); while (true) { std::shared_ptr<ParallelAddTask> completedTask = std::dynamic_pointer_cast<ParallelAddTask>(pool.getCompletedTask()); if (!completedTask) return false; //Last level reached, set the result if (completedTask->level == numLevels) { parallelSum = completedTask->number[0]; break; } //If we have stored another task at the same level, create a new task if (storedTasks[completedTask->level]) { completedTask->number[1] = storedTasks[completedTask->level]->number[0]; storedTasks[completedTask->level] = nullptr; pool.addTask(completedTask); } else { //Store the task for now storedTasks[completedTask->level] = completedTask; } } //Stop the threads pool.stopHandlingTasks(); //Join the threads pool.join(); //Check that no exception occured if (pool.getThreadException()) return false; //Check the sum if (parallelSum != ((numValues*(numValues + 1)) / 2)) return false; return true; }