From c163d65da7a7a28a2359305084be911a6f44d785 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:29:03 +0100 Subject: [PATCH] Documentation for Thread Former-commit-id: b33bbdf473792ddcde8ffbe310722d83a1a12bcf --- include/Nazara/Core/TaskScheduler.inl | 25 +++++ include/Nazara/Core/Thread.inl | 25 +++++ include/Nazara/Core/ThreadSafety.hpp | 4 +- include/Nazara/Core/ThreadSafetyOff.hpp | 4 +- src/Nazara/Core/TaskScheduler.cpp | 50 +++++++++ src/Nazara/Core/Thread.cpp | 128 ++++++++++++++++++++++++ 6 files changed, 232 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/TaskScheduler.inl b/include/Nazara/Core/TaskScheduler.inl index b8b99ed47..ba64cfb1a 100644 --- a/include/Nazara/Core/TaskScheduler.inl +++ b/include/Nazara/Core/TaskScheduler.inl @@ -6,18 +6,43 @@ namespace Nz { + /*! + * \class Nz::TaskScheduler + * \brief Core class that represents a thread pool + */ + + /*! + * \brief Adds a task to the pending list + * + * \param function Task that the pool will execute + */ + template void TaskScheduler::AddTask(F function) { AddTaskFunctor(new FunctorWithoutArgs(function)); } + /*! + * \brief Adds a task to the pending list + * + * \param function Task that the pool will execute + * \param args Arguments of the function + */ + template void TaskScheduler::AddTask(F function, Args&&... args) { AddTaskFunctor(new FunctorWithArgs(function, std::forward(args)...)); } + /*! + * \brief Adds a task to the pending list + * + * \param function Task that the pool will execute + * \param object Object on which the method will be called + */ + template void TaskScheduler::AddTask(void (C::*function)(), C* object) { diff --git a/include/Nazara/Core/Thread.inl b/include/Nazara/Core/Thread.inl index d6c76522a..f3de4ae24 100644 --- a/include/Nazara/Core/Thread.inl +++ b/include/Nazara/Core/Thread.inl @@ -7,18 +7,43 @@ namespace Nz { + /*! + * \class Nz::Thread + * \brief Core class that represents a thread + */ + + /*! + * \brief Constructs a Thread object with a function + * + * \param function Task the thread will execute in parallel + */ + template Thread::Thread(F function) { CreateImpl(new FunctorWithoutArgs(function)); } + /*! + * \brief Constructs a Thread object with a function and its parameters + * + * \param function Task the thread will execute in parallel + * \param args Arguments of the function + */ + template Thread::Thread(F function, Args&&... args) { CreateImpl(new FunctorWithArgs(function, std::forward(args)...)); } + /*! + * \brief Constructs a Thread object with a member function and its object + * + * \param function Task the thread will execute in parallel + * \param object Object on which the method will be called + */ + template Thread::Thread(void (C::*function)(), C* object) { diff --git a/include/Nazara/Core/ThreadSafety.hpp b/include/Nazara/Core/ThreadSafety.hpp index 26b446ae6..5b1629b5b 100644 --- a/include/Nazara/Core/ThreadSafety.hpp +++ b/include/Nazara/Core/ThreadSafety.hpp @@ -2,12 +2,12 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Pas de header guard +// No header guard #include #include -// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise dans une même unité de compilation +// These macroes can change for any file which uses it in the same unit of compilation #undef NazaraLock #undef NazaraMutex #undef NazaraMutexAttrib diff --git a/include/Nazara/Core/ThreadSafetyOff.hpp b/include/Nazara/Core/ThreadSafetyOff.hpp index e6a1ce208..29c327e0d 100644 --- a/include/Nazara/Core/ThreadSafetyOff.hpp +++ b/include/Nazara/Core/ThreadSafetyOff.hpp @@ -2,9 +2,9 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Pas de header guard +// No header guard -// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise dans une même unité de compilation +// These macroes can change for any file which uses it in the same unit of compilation #undef NazaraLock #undef NazaraMutex #undef NazaraMutexAttrib diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index 27d071987..108e120b1 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -24,16 +24,39 @@ namespace Nz unsigned int s_workerCount = 0; } + /*! + * \class Nz::TaskScheduler + * \brief Core class that represents a pool of threads + * + * \remark Initialized should be called first + */ + + /*! + * \brief Gets the number of threads + * \return Number of threads, if none, the number of simulatenous threads on the processor is returned + */ + unsigned int TaskScheduler::GetWorkerCount() { return (s_workerCount > 0) ? s_workerCount : HardwareInfo::GetProcessorCount(); } + /*! + * \brief Initializes the TaskScheduler class + * \return true if everything is ok + */ + bool TaskScheduler::Initialize() { return TaskSchedulerImpl::Initialize(GetWorkerCount()); } + /*! + * \brief Runs the pending works + * + * \remark Produce a NazaraError if the class is not initialized + */ + void TaskScheduler::Run() { if (!Initialize()) @@ -49,6 +72,14 @@ namespace Nz } } + /*! + * \brief Sets the number of workers + * + * \param workerCount Number of simulatnous threads handling the tasks + * + * \remark Produce a NazaraError if the class is not initialized and NAZARA_CORE_SAFE is defined + */ + void TaskScheduler::SetWorkerCount(unsigned int workerCount) { #ifdef NAZARA_CORE_SAFE @@ -62,12 +93,22 @@ namespace Nz s_workerCount = workerCount; } + /*! + * \brief Uninitializes the TaskScheduler class + */ + void TaskScheduler::Uninitialize() { if (TaskSchedulerImpl::IsInitialized()) TaskSchedulerImpl::Uninitialize(); } + /*! + * \brief Waits for tasks to be done + * + * \remark Produce a NazaraError if the class is not initialized + */ + void TaskScheduler::WaitForTasks() { if (!Initialize()) @@ -79,6 +120,15 @@ namespace Nz TaskSchedulerImpl::WaitForTasks(); } + /*! + * \brief Adds a task on the pending list + * + * \param taskFunctor Functor represeting a task to be done + * + * \remark Produce a NazaraError if the class is not initialized + * \remark A task containing a call on this class is undefined behaviour + */ + void TaskScheduler::AddTaskFunctor(Functor* taskFunctor) { if (!Initialize()) diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index 105067baf..da01025d3 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -21,17 +21,36 @@ namespace Nz { + /*! + * \class Nz::Thread + * \brief Core class that represents a thread + */ + + /*! + * \brief Constructs a Thread object by default + */ + Thread::Thread() : m_impl(nullptr) { } + /*! + * \brief Constructs a Thread object by move semantic + * + * \param other Thread to move into this + */ + Thread::Thread(Thread&& other) noexcept : m_impl(other.m_impl) { other.m_impl = nullptr; } + /*! + * \brief Waits that the thread ends and then destroys this + */ + Thread::~Thread() { if (m_impl) @@ -42,6 +61,10 @@ namespace Nz } } + /*! + * \brief Detaches the thread + */ + void Thread::Detach() { if (m_impl) @@ -52,16 +75,32 @@ namespace Nz } } + /*! + * \brief Gets the id of the thread + * \return The identifiant of the thread (PID) + */ + Thread::Id Thread::GetId() const { return Thread::Id(m_impl); } + /*! + * \brief Checks whether the thread can be joined + * \return true if well formed and not detached + */ + bool Thread::IsJoinable() const { return m_impl != nullptr; } + /*! + * \brief Waits that the thread ends + * + * \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined + */ + void Thread::Join() { #if NAZARA_CORE_SAFE @@ -77,6 +116,16 @@ namespace Nz m_impl = nullptr; } + /*! + * \brief Moves the other thread into this + * \return A reference to this + * + * \param thread Thread to move in this + * + * \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined + * \remark And call std::terminate if no functor was assigned and NAZARA_CORE_SAFE is defined + */ + Thread& Thread::operator=(Thread&& thread) { #if NAZARA_CORE_SAFE @@ -91,16 +140,33 @@ namespace Nz return *this; } + /*! + * \brief Gets the number of simulatenous threads that can run on the same cpu + * \return The number of simulatenous threads + */ + unsigned int Thread::HardwareConcurrency() { return HardwareInfo::GetProcessorCount(); } + /*! + * \brief Makes sleep this thread + * + * \param milliseconds The number of milliseconds to sleep + */ + void Thread::Sleep(UInt32 milliseconds) { ThreadImpl::Sleep(milliseconds); } + /*! + * \brief Creates the implementation of this thread + * + * \param functor The task the thread will represent + */ + void Thread::CreateImpl(Functor* functor) { m_impl = new ThreadImpl(functor); @@ -108,41 +174,103 @@ namespace Nz /*********************************Thread::Id********************************/ + /*! + * \brief Constructs a Thread object with a thread implementation + * + * \param thread Thread implementation assigned to the thread + */ + Thread::Id::Id(ThreadImpl* thread) : m_id(thread) { } + /*! + * \brief Compares two Thread::Id + * \return true if the two thread ids are the same + * + * \param lhs First id + * \param rhs Second id + */ + bool operator==(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id == rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return false if the two thread ids are the same + * + * \param lhs First id + * \param rhs Second id + */ + bool operator!=(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id != rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is inferior to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator<(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id < rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is inferior or equal to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator<=(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id <= rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is superior to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator>(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id > rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is superior or equal to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator>=(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id >= rhs.m_id; } + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param id The thread id to output + */ + std::ostream& operator<<(std::ostream& o, const Nz::Thread::Id& id) { o << id.m_id;