Commit af4b5463 authored by Dave Moxey's avatar Dave Moxey

Minor fixes to code formatting for guidelines and readability

parent 2d0f0e32
......@@ -153,8 +153,8 @@ ThreadMaster& GetThreadMaster()
/**
* @param p_type String to be passed to the ThreadManagerFactory
*
* Subsequent CreateInstance calls will pass this string to the ThreadManagerFactory
* to create a ThreadManager.
* Subsequent CreateInstance calls will pass this string to the
* ThreadManagerFactory to create a ThreadManager.
*
* It is an error to call this more than once (since having different kinds of
* ThreadManager active is probably a stupendously bad idea).
......
......@@ -73,7 +73,8 @@ enum SchedType
class ThreadManager;
typedef boost::shared_ptr<ThreadManager> ThreadManagerSharedPtr;
typedef LibUtilities::NekFactory< std::string, ThreadManager, unsigned int> ThreadManagerFactory;
typedef LibUtilities::NekFactory<std::string, ThreadManager, unsigned int>
ThreadManagerFactory;
LIB_UTILITIES_EXPORT ThreadManagerFactory& GetThreadManagerFactory();
/**
......@@ -95,7 +96,8 @@ LIB_UTILITIES_EXPORT ThreadManagerFactory& GetThreadManagerFactory();
* Instance of the subclass will be destructed once the ThreadManager has
* finished the Run() method.
*/
class ThreadJob {
class ThreadJob
{
public:
/// Base constructor
ThreadJob();
......@@ -122,7 +124,6 @@ class ThreadJob {
private:
unsigned int m_workerNum;
};
......@@ -172,12 +173,11 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
* @brief Pass a list of tasklets to the master queue.
* @param joblist Vector of ThreadJob pointers.
*
* The list of jobs is copied into the master queue.
* Jobs may be available for running *immediately*,
* even before the list has been fully copied. This can
* have consequences for the scheduling.
* If this is an issue then suspend the workers with SetNumWorkers(0)
* until the jobs are queued.
* The list of jobs is copied into the master queue. Jobs may be
* available for running *immediately*, even before the list has been
* fully copied. This can have consequences for the scheduling. If
* this is an issue then suspend the workers with SetNumWorkers(0) until
* the jobs are queued.
*
* @see SchedType
*/
......@@ -186,9 +186,9 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
* @brief Pass a single job to the master queue.
* @param job A pointer to a ThreadJob subclass.
*
* The job may become available for running immediately.
* If this is an issue then suspend the workers with SetNumWorkers(0)
* until the jobs are queued.
* The job may become available for running immediately. If this is an
* issue then suspend the workers with SetNumWorkers(0) until the jobs
* are queued.
*/
virtual void QueueJob(ThreadJob* job) = 0;
/**
......@@ -201,34 +201,31 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
/**
* @brief Returns the worker number of the executing thread.
*
* Returns an unsigned int between 0 and N-1 where N is the
* number of active worker threads. Repeated calls from within
* this thread will always return the same value and the value
* will be the same as returned from ThreadJob.GetWorkerNum().
* The same thread will run a job until it finishes.
* Returns an unsigned int between 0 and N-1 where N is the number of
* active worker threads. Repeated calls from within this thread will
* always return the same value and the value will be the same as
* returned from ThreadJob.GetWorkerNum(). The same thread will run a
* job until it finishes.
*
* Although if there are active threads then thread 0 is always
* one of them, it is possible that thread 0 does not run for
* a given set of jobs. For example, if there are 4 active threads
* and 3 jobs are submitted with a e_static scheduling strategy
* and a chunksize of 1, then it is possible that threads 1,2,
* and 3 pick up the jobs and thread 0 remains idle.
* Although if there are active threads then thread 0 is always one of
* them, it is possible that thread 0 does not run for a given set of
* jobs. For example, if there are 4 active threads and 3 jobs are
* submitted with a e_static scheduling strategy and a chunksize of 1,
* then it is possible that threads 1,2, and 3 pick up the jobs and
* thread 0 remains idle.
*
* Returns 0 if called by non-thread.
*
*
*/
virtual unsigned int GetWorkerNum() = 0;
/**
* @brief Sets the number of active workers.
* @param num The number of active workers.
*
* Active workers are threads that are either running jobs
* or are waiting for jobs to be queued.
* Active workers are threads that are either running jobs or are
* waiting for jobs to be queued.
*
* If num is greater than the maximum allowed number
* of active workers, then the maximum value will be
* used instead.
* If num is greater than the maximum allowed number of active workers,
* then the maximum value will be used instead.
*/
virtual void SetNumWorkers(const unsigned int num) = 0;
/**
......@@ -246,12 +243,11 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
* @brief Waits until all queued jobs are finished.
*
* If there are no jobs running or queued this method returns
* immediately. Otherwise it blocks until the queue is empty
* and the worker threads are idle.
* immediately. Otherwise it blocks until the queue is empty and the
* worker threads are idle.
*
* Implementations *must*
* ensure that trivial deadlocks are not possible from this method,
* that is, that this code:
* Implementations *must* ensure that trivial deadlocks are not possible
* from this method, that is, that this code:
* @code
* // assume ThreadManager* tm
* // assume SomeJob is subclass of ThreadJob
......@@ -261,15 +257,16 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
* tm->QueueJob(job);
* tm->Wait();
* @endcode
* does not wait forever. Since the master thread is counted in
* the number of worker threads, implementations should increase
* the number of active workers by 1 on entering Wait().
* does not wait forever. Since the master thread is counted in the
* number of worker threads, implementations should increase the number
* of active workers by 1 on entering Wait().
*/
virtual void Wait() = 0;
/**
* @brief Controls how many jobs are sent to each worker at a time.
*
* The exact meaning of this parameter depends on the current scheduling algorithm.
* The exact meaning of this parameter depends on the current scheduling
* algorithm.
*
* @see SchedType
* @see SetSchedType()
......@@ -286,10 +283,12 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
*/
virtual bool InThread() = 0;
/**
* @brief A calling threads holds until all active threads call this method.
* @brief A calling threads holds until all active threads call this
* method.
*
* When called, the calling thread will sleep until all active workers have called
* this method. Once all have done so all threads awake and continue execution.
* When called, the calling thread will sleep until all active workers
* have called this method. Once all have done so all threads awake and
* continue execution.
*
* @note Behaviour is likely undefined if the number of active workers
* is altered after a thread has called this method. It is only safe to
......@@ -320,10 +319,8 @@ class ThreadManager : public boost::enable_shared_from_this<ThreadManager>
{
return pRank * GetMaxNumWorkers() + pThr;
}
};
typedef boost::unique_lock<boost::shared_mutex> WriteLock;
typedef boost::shared_lock<boost::shared_mutex> ReadLock;
......@@ -334,8 +331,8 @@ typedef boost::shared_lock<boost::shared_mutex> ReadLock;
* simple implementation of ThreadManager, ThreadStartupManager, which behaves
* as a single-threaded ThreadManager that fails if anything non-trivial is
* attempted. This means code should be cautious about caching the value of
* GetInstance(string), as it might change once that particular threading
* system is initialised.
* GetInstance(string), as it might change once that particular threading system
* is initialised.
*
* Multiple ThreadManagers should now be possible. Each is identified with a
* string and can be recovered by calling
......
......@@ -54,9 +54,9 @@ std::string ThreadManagerBoost::className =
* @note Do not use, use factory instead.
*/
ThreadManagerBoost::ThreadManagerBoost(unsigned int numT) :
m_numThreads(numT), m_numWorkers(numT), m_masterQueue(), m_masterQueueMutex(),
m_masterActiveMutex(), m_masterQueueCondVar(), m_masterActiveCondVar(),
m_chunkSize(1), m_schedType(e_dynamic),
m_numThreads(numT), m_numWorkers(numT), m_masterQueue(),
m_masterQueueMutex(), m_masterActiveMutex(), m_masterQueueCondVar(),
m_masterActiveCondVar(), m_chunkSize(1), m_schedType(e_dynamic),
m_threadMap()
{
using namespace std;
......@@ -321,12 +321,14 @@ const std::string& ThreadManagerBoost::GetType() const
/**
* @param threadManager Pointer to the ThreadManagerBoost that is controlling this worker.
* @param threadManager Pointer to the ThreadManagerBoost that is controlling
* this worker.
* @param workerNum Unique number from 0..(number_of_threads - 1)
*
* Called by the ThreadManagerBoost instance.
*/
ThreadWorkerBoost::ThreadWorkerBoost(ThreadManagerBoost *tm, unsigned int workerNum) :
ThreadWorkerBoost::ThreadWorkerBoost(
ThreadManagerBoost *tm, unsigned int workerNum) :
m_threadManager(tm), m_workerQueue(),
m_keepgoing(true), m_threadNum(workerNum)
{
......@@ -343,7 +345,7 @@ ThreadWorkerBoost::~ThreadWorkerBoost()
if (m_keepgoing)
{
std::cerr << "Warning: ThreadWorker: " << m_threadNum
<< "destroyed while running!" << std::endl;
<< "destroyed while running!" << std::endl;
}
// on destuction the m_workerQueue will be destructed and that
// will destruct any ThreadJobs still in there.
......@@ -395,8 +397,11 @@ unsigned int ThreadWorkerBoost::GetNumToLoad()
switch (m_threadManager->m_schedType)
{
case e_guided:
numToLoad = std::max(static_cast<unsigned long>(m_threadManager->m_chunkSize),
static_cast<unsigned long>(m_threadManager->m_masterQueue.size() / (2*m_threadManager->m_numWorkers +1)));
numToLoad = std::max(
static_cast<unsigned long>(m_threadManager->m_chunkSize),
static_cast<unsigned long>(
m_threadManager->m_masterQueue.size()
/ (2*m_threadManager->m_numWorkers +1)));
break;
case e_dynamic:
......
......@@ -58,7 +58,6 @@ class ThreadWorkerBoost;
*/
class ThreadManagerBoost: public ThreadManager
{
/**
* So the workers can access the master queue and locks.
*/
......@@ -87,7 +86,8 @@ class ThreadManagerBoost: public ThreadManager
/// Called by the factory method.
static ThreadManagerSharedPtr Create(unsigned int numT)
{
return boost::shared_ptr<ThreadManager>(new ThreadManagerBoost(numT));
return boost::shared_ptr<ThreadManager>(
new ThreadManagerBoost(numT));
}
private:
......@@ -97,24 +97,24 @@ class ThreadManagerBoost: public ThreadManager
void SetNumWorkersImpl(const unsigned int num);
// Member variables
const unsigned int m_numThreads;
unsigned int m_numWorkers;
std::queue<ThreadJob*> m_masterQueue;
boost::mutex m_masterQueueMutex;
boost::mutex m_masterActiveMutex;
boost::condition_variable m_masterQueueCondVar;
boost::condition_variable m_masterActiveCondVar;
ThreadWorkerBoost** m_threadList;
boost::thread** m_threadThreadList;
boost::thread::id m_masterThreadId;
bool* m_threadBusyList;
bool* m_threadActiveList;
unsigned int m_chunkSize;
SchedType m_schedType;
boost::barrier *m_barrier;
std::map<boost::thread::id, unsigned int> m_threadMap;
static std::string className;
std::string m_type;
const unsigned int m_numThreads;
unsigned int m_numWorkers;
std::queue<ThreadJob*> m_masterQueue;
boost::mutex m_masterQueueMutex;
boost::mutex m_masterActiveMutex;
boost::condition_variable m_masterQueueCondVar;
boost::condition_variable m_masterActiveCondVar;
ThreadWorkerBoost** m_threadList;
boost::thread** m_threadThreadList;
boost::thread::id m_masterThreadId;
bool* m_threadBusyList;
bool* m_threadActiveList;
unsigned int m_chunkSize;
SchedType m_schedType;
boost::barrier* m_barrier;
std::map<boost::thread::id, unsigned int> m_threadMap;
static std::string className;
std::string m_type;
};
/**
......@@ -123,27 +123,29 @@ class ThreadManagerBoost: public ThreadManager
* Each instance of this class corresponds to a worker thread.
* Instances manage their own queue of jobs to run, grabbing new
* jobs from the master queue when it is exhausted.
*
*/
class ThreadWorkerBoost
{
public:
/// Constructor
ThreadWorkerBoost(ThreadManagerBoost *threadManager, unsigned int workerNum);
ThreadWorkerBoost(ThreadManagerBoost *threadManager,
unsigned int workerNum);
/// Destructor.
~ThreadWorkerBoost();
/// This provides the interface that boost::thread uses to start the worker.
/// This provides the interface that boost::thread uses to start the
/// worker.
void operator()() { MainLoop(); };
/**
* @brief Return the index of the worker thread.
* @returns Index of worker thread, an integer between 0 and (number_of_threads - 1)
* @return Index of worker thread, an integer between 0 and
* (number_of_threads - 1)
*/
unsigned int GetWorkerNum() { return m_threadNum; };
/**
* @brief A signal to shut down.
*
* If this method is called the worker will shut down. Used by
* the ThreadManagerBoost to stop threading.
* If this method is called the worker will shut down. Used by the
* ThreadManagerBoost to stop threading.
*/
void Stop() { m_keepgoing = false;} ;
......@@ -157,11 +159,10 @@ class ThreadWorkerBoost
void RunJobs();
// Member variables
ThreadManagerBoost *m_threadManager;
std::queue<ThreadJob *> m_workerQueue;
bool m_keepgoing;
unsigned int m_threadNum;
ThreadManagerBoost* m_threadManager;
std::queue<ThreadJob *> m_workerQueue;
bool m_keepgoing;
unsigned int m_threadNum;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment