Mantid
Loading...
Searching...
No Matches
ThreadPoolRunnable.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9#include "MantidKernel/Task.h"
11
12#include <Poco/Thread.h>
13
14namespace Mantid::Kernel {
15
16//-----------------------------------------------------------------------------------
27ThreadPoolRunnable::ThreadPoolRunnable(size_t threadnum, ThreadScheduler *scheduler, ProgressBase *prog, double waitSec)
28 : m_threadnum(threadnum), m_scheduler(scheduler), m_prog(prog), m_waitSec(waitSec) {
29 if (!m_scheduler)
30 throw std::invalid_argument("NULL ThreadScheduler passed to ThreadPoolRunnable::ctor()");
31}
32
33//-----------------------------------------------------------------------------------
36
37//-----------------------------------------------------------------------------------
42 std::shared_ptr<Task> task;
43
44 // If there are no tasks yet, wait up to m_waitSec for them to come up
45 while (m_scheduler->empty() && m_waitSec > 0.0) {
46 Poco::Thread::sleep(10); // millisec
47 m_waitSec -= 0.01; // Subtract ten millisec from the time left to wait.
48 }
49
50 while (!m_scheduler->empty()) {
51 // Request the task from the scheduler.
52 // Will be NULL if not found.
54
55 if (task) {
56 // Task-specific mutex if specified?
57 std::shared_ptr<std::mutex> mutex = task->getMutex();
58 if (bool(mutex))
59 mutex->lock();
60
61 try {
62 // Run the task (synchronously within this thread)
63 task->run();
64 } catch (std::exception &e) {
65 // The task threw an exception!
66 // This will clear out the list of tasks, allowing all threads to
67 // finish.
68 m_scheduler->abort(std::runtime_error(e.what()));
69 }
70
71 // Tell the scheduler that we finished this task
72 m_scheduler->finished(task.get(), m_threadnum);
73
74 // Report progress, if specified.
75 if (m_prog)
76 m_prog->report();
77
78 // Unlock the mutex, if any.
79 if (mutex)
80 mutex->unlock();
81
82 // We now delete the task to free up memory
83 } else {
84 // No appropriate task for this thread (perhaps a mutex is locked)
85 // but there are more tasks.
86 // So we wait a bit before checking again.
87 Poco::Thread::sleep(10); // millisec
88 }
89 }
90 // Ran out of tasks that could be run.
91 // Thread now will exit
92}
93
94} // namespace Mantid::Kernel
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
double m_waitSec
How many seconds you are allowed to wait with no tasks before exiting.
void run() override
Thread method.
void clearWait()
Clear the wait time of the runnable so that it stops waiting for tasks.
size_t m_threadnum
ID of this thread.
ProgressBase * m_prog
Progress reporter.
ThreadScheduler * m_scheduler
The ThreadScheduler instance taking care of task scheduling.
ThreadPoolRunnable(size_t threadnum, ThreadScheduler *scheduler, ProgressBase *prog=nullptr, double waitSec=0.0)
Constructor.
The ThreadScheduler object defines how tasks are allocated to threads and in what order.
virtual void abort(std::runtime_error exception)
Signal to the scheduler that a task is complete.
virtual void finished(Task *task, size_t threadnum)
Signal to the scheduler that a task is complete.
virtual std::shared_ptr< Task > pop(size_t threadnum)=0
Retrieves the next Task to execute.
virtual bool empty()=0
Returns true if the queue is empty.