281 lines
5.5 KiB
C++
281 lines
5.5 KiB
C++
// Copyright (C) 2017 Jérôme Leclercq
|
|
// This file is part of the "Nazara Engine - Core module"
|
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
|
|
#include <Nazara/Core/Thread.hpp>
|
|
#include <Nazara/Core/Config.hpp>
|
|
#include <Nazara/Core/Error.hpp>
|
|
#include <Nazara/Core/HardwareInfo.hpp>
|
|
#include <Nazara/Core/MovablePtr.hpp>
|
|
#include <ostream>
|
|
|
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
|
#include <Nazara/Core/Win32/ThreadImpl.hpp>
|
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
|
#include <Nazara/Core/Posix/ThreadImpl.hpp>
|
|
#else
|
|
#error Thread has no implementation
|
|
#endif
|
|
|
|
#include <Nazara/Core/Debug.hpp>
|
|
|
|
namespace Nz
|
|
{
|
|
/*!
|
|
* \ingroup core
|
|
* \class Nz::Thread
|
|
* \brief Core class that represents a thread
|
|
*/
|
|
|
|
/*!
|
|
* \brief Constructs a Thread<T> object by default
|
|
*/
|
|
|
|
Thread::Thread() :
|
|
m_impl(nullptr)
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* \brief Waits that the thread ends and then destroys this
|
|
*/
|
|
|
|
Thread::~Thread()
|
|
{
|
|
if (m_impl)
|
|
{
|
|
m_impl->Join();
|
|
delete m_impl;
|
|
m_impl = nullptr;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Detaches the thread
|
|
*/
|
|
|
|
void Thread::Detach()
|
|
{
|
|
if (m_impl)
|
|
{
|
|
m_impl->Detach();
|
|
delete m_impl;
|
|
m_impl = nullptr;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \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
|
|
if (!m_impl)
|
|
{
|
|
NazaraError("This thread is not joinable");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
m_impl->Join();
|
|
delete m_impl;
|
|
m_impl = nullptr;
|
|
}
|
|
|
|
/*!
|
|
* \brief Changes the debugging name associated to a thread
|
|
*
|
|
* Changes the debugging name associated with a particular thread, and may helps with debugging tools.
|
|
*
|
|
* \param name The new name of the thread
|
|
*
|
|
* \remark Due to system limitations, thread name cannot exceed 15 characters (excluding null-terminator)
|
|
*
|
|
* \see SetCurrentThreadName
|
|
*/
|
|
void Thread::SetName(const String& name)
|
|
{
|
|
NazaraAssert(m_impl, "Invalid thread");
|
|
NazaraAssert(name.GetSize() < 16, "Thread name is too long");
|
|
|
|
m_impl->SetName(name);
|
|
}
|
|
|
|
/*!
|
|
* \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 Changes the debugging name associated to the calling thread
|
|
*
|
|
* Changes the debugging name associated with the calling thread, and may helps with debugging tools.
|
|
*
|
|
* \param name The new name associated with this thread
|
|
*
|
|
* \remark Due to system limitations, thread name cannot exceed 15 characters (excluding null-terminator)
|
|
*
|
|
* \see SetName
|
|
*/
|
|
void Thread::SetCurrentThreadName(const String& name)
|
|
{
|
|
NazaraAssert(name.GetSize() < 16, "Thread name is too long");
|
|
|
|
ThreadImpl::SetCurrentName(name);
|
|
}
|
|
|
|
/*!
|
|
* \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);
|
|
}
|
|
|
|
/*********************************Thread::Id********************************/
|
|
|
|
/*!
|
|
* \brief Constructs a Thread<T> 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;
|
|
return o;
|
|
}
|
|
}
|