Made use of atomic variables

In order to replace mutex-protected integer values (Performance
improvement)


Former-commit-id: d40ed2444111f00dab372f2371fe91cfd9cd2472
This commit is contained in:
Lynix 2013-05-03 23:12:58 +02:00
parent aa1399b750
commit 459c7a4d07
8 changed files with 41 additions and 118 deletions

View File

@ -8,6 +8,7 @@
#define NAZARA_RESOURCE_HPP #define NAZARA_RESOURCE_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <atomic>
#include <set> #include <set>
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE
@ -52,7 +53,7 @@ class NAZARA_API NzResource
bool RemoveResourceListener(NzResourceListener* listener) const; bool RemoveResourceListener(NzResourceListener* listener) const;
bool RemoveResourceReference() const; bool RemoveResourceReference() const;
void SetPersistent(bool persistent = true, bool checkReferenceCount = false); bool SetPersistent(bool persistent = true, bool checkReferenceCount = false);
protected: protected:
void NotifyCreated(); void NotifyCreated();
@ -67,8 +68,8 @@ class NAZARA_API NzResource
mutable std::set<NzResourceEntry> m_resourceListeners; mutable std::set<NzResourceEntry> m_resourceListeners;
mutable std::set<NzResourceEntry> m_resourceListenersCache; mutable std::set<NzResourceEntry> m_resourceListenersCache;
mutable bool m_resourceListenerUpdated; mutable bool m_resourceListenerUpdated;
bool m_resourcePersistent; std::atomic_bool m_resourcePersistent;
mutable unsigned int m_resourceReferenceCount; mutable std::atomic_uint m_resourceReferenceCount;
}; };
#endif // NAZARA_RESOURCE_HPP #endif // NAZARA_RESOURCE_HPP

View File

@ -9,16 +9,11 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Hashable.hpp> #include <Nazara/Core/Hashable.hpp>
#include <atomic>
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
#include <vector> #include <vector>
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_STRING
#include <Nazara/Core/ThreadSafety.hpp>
#else
#include <Nazara/Core/ThreadSafetyOff.hpp>
#endif
class NzAbstractHash; class NzAbstractHash;
class NzHashDigest; class NzHashDigest;
@ -282,7 +277,10 @@ class NAZARA_API NzString : public NzHashable
struct NAZARA_API SharedString struct NAZARA_API SharedString
{ {
SharedString() = default; SharedString() :
refCount(1)
{
}
SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) : SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) :
capacity(bufferSize), capacity(bufferSize),
@ -296,8 +294,7 @@ class NAZARA_API NzString : public NzHashable
unsigned int size; unsigned int size;
char* string; char* string;
unsigned short refCount = 1; std::atomic_ushort refCount;
NazaraMutex(mutex)
}; };
static SharedString emptyString; static SharedString emptyString;

View File

@ -19,12 +19,7 @@
#include <Nazara/Utility/CubemapParams.hpp> #include <Nazara/Utility/CubemapParams.hpp>
#include <Nazara/Utility/Enums.hpp> #include <Nazara/Utility/Enums.hpp>
#include <Nazara/Utility/PixelFormat.hpp> #include <Nazara/Utility/PixelFormat.hpp>
#include <atomic>
#if NAZARA_UTILITY_THREADSAFE && NAZARA_THREADSAFETY_IMAGE
#include <Nazara/Core/ThreadSafety.hpp>
#else
#include <Nazara/Core/ThreadSafetyOff.hpp>
#endif
///TODO: Filtres ///TODO: Filtres
@ -137,8 +132,7 @@ class NAZARA_API NzImage : public NzResource
unsigned int height; unsigned int height;
unsigned int width; unsigned int width;
unsigned short refCount = 1; std::atomic_ushort refCount;
NazaraMutex(mutex)
}; };
static SharedImage emptyImage; static SharedImage emptyImage;

View File

@ -17,7 +17,7 @@ m_resourceReferenceCount(0)
} }
NzResource::NzResource(const NzResource& resource) : NzResource::NzResource(const NzResource& resource) :
m_resourcePersistent(resource.m_resourcePersistent), m_resourcePersistent(resource.m_resourcePersistent.load()),
m_resourceReferenceCount(0) m_resourceReferenceCount(0)
{ {
} }
@ -49,22 +49,16 @@ void NzResource::AddResourceListener(NzResourceListener* listener, int index) co
void NzResource::AddResourceReference() const void NzResource::AddResourceReference() const
{ {
NazaraLock(m_mutex)
m_resourceReferenceCount++; m_resourceReferenceCount++;
} }
unsigned int NzResource::GetResourceReferenceCount() const unsigned int NzResource::GetResourceReferenceCount() const
{ {
NazaraLock(m_mutex)
return m_resourceReferenceCount; return m_resourceReferenceCount;
} }
bool NzResource::IsPersistent() const bool NzResource::IsPersistent() const
{ {
NazaraLock(m_mutex)
return m_resourcePersistent; return m_resourcePersistent;
} }
@ -77,34 +71,11 @@ bool NzResource::RemoveResourceListener(NzResourceListener* listener) const
else else
NazaraError(NzString::Pointer(listener) + " is not a listener of " + NzString::Pointer(this)); NazaraError(NzString::Pointer(listener) + " is not a listener of " + NzString::Pointer(this));
// RemoveResourceReference() return RemoveResourceReference();
#if NAZARA_CORE_SAFE
if (m_resourceReferenceCount == 0)
{
NazaraError("Impossible to remove reference (Ref. counter is already 0)");
return false;
}
#endif
if (--m_resourceReferenceCount == 0 && !m_resourcePersistent)
{
NazaraMutexUnlock(m_mutex);
delete this;
return true; // On vient d'être supprimé
}
else
{
NazaraMutexUnlock(m_mutex);
return false;
}
} }
bool NzResource::RemoveResourceReference() const bool NzResource::RemoveResourceReference() const
{ {
NazaraMutexLock(m_mutex);
#if NAZARA_CORE_SAFE #if NAZARA_CORE_SAFE
if (m_resourceReferenceCount == 0) if (m_resourceReferenceCount == 0)
{ {
@ -115,35 +86,27 @@ bool NzResource::RemoveResourceReference() const
if (--m_resourceReferenceCount == 0 && !m_resourcePersistent) if (--m_resourceReferenceCount == 0 && !m_resourcePersistent)
{ {
NazaraMutexUnlock(m_mutex); delete this; // Suicide
return true;
}
else
return false;
}
bool NzResource::SetPersistent(bool persistent, bool checkReferenceCount)
{
m_resourcePersistent = persistent;
if (checkReferenceCount && !persistent && m_resourceReferenceCount == 0)
{
delete this; delete this;
return true; return true;
} }
else else
{
NazaraMutexUnlock(m_mutex);
return false; return false;
} }
}
void NzResource::SetPersistent(bool persistent, bool checkReferenceCount)
{
NazaraMutexLock(m_mutex);
m_resourcePersistent = persistent;
if (checkReferenceCount && !persistent && m_resourceReferenceCount == 0)
{
NazaraMutexUnlock(m_mutex);
delete this;
}
else
{
NazaraMutexUnlock(m_mutex);
}
}
void NzResource::NotifyCreated() void NzResource::NotifyCreated()
{ {

View File

@ -136,11 +136,7 @@ NzString::NzString(const NzString& string) :
m_sharedString(string.m_sharedString) m_sharedString(string.m_sharedString)
{ {
if (m_sharedString != &emptyString) if (m_sharedString != &emptyString)
{
NazaraMutexLock(m_sharedString->mutex);
m_sharedString->refCount++; m_sharedString->refCount++;
NazaraMutexUnlock(m_sharedString->mutex);
}
} }
NzString::NzString(NzString&& string) noexcept : NzString::NzString(NzString&& string) noexcept :
@ -4237,11 +4233,7 @@ NzString& NzString::operator=(const NzString& string)
m_sharedString = string.m_sharedString; m_sharedString = string.m_sharedString;
if (m_sharedString != &emptyString) if (m_sharedString != &emptyString)
{
NazaraMutexLock(m_sharedString->mutex);
m_sharedString->refCount++; m_sharedString->refCount++;
NazaraMutexUnlock(m_sharedString->mutex);
}
return *this; return *this;
} }
@ -5091,7 +5083,6 @@ void NzString::EnsureOwnership()
if (m_sharedString == &emptyString) if (m_sharedString == &emptyString)
return; return;
NazaraLock(m_sharedString->mutex);
if (m_sharedString->refCount > 1) if (m_sharedString->refCount > 1)
{ {
m_sharedString->refCount--; m_sharedString->refCount--;
@ -5115,11 +5106,7 @@ void NzString::ReleaseString()
if (m_sharedString == &emptyString) if (m_sharedString == &emptyString)
return; return;
NazaraMutexLock(m_sharedString->mutex); if (--m_sharedString->refCount == 0)
bool freeSharedString = (--m_sharedString->refCount == 0);
NazaraMutexUnlock(m_sharedString->mutex);
if (freeSharedString)
{ {
delete[] m_sharedString->string; delete[] m_sharedString->string;
delete m_sharedString; delete m_sharedString;

View File

@ -9,6 +9,7 @@
#include <Nazara/Core/LockGuard.hpp> #include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp> #include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/Thread.hpp> #include <Nazara/Core/Thread.hpp>
#include <atomic>
#include <queue> #include <queue>
#include <vector> #include <vector>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
@ -28,7 +29,7 @@ namespace
NzMutex waiterConditionVariableMutex; NzMutex waiterConditionVariableMutex;
NzMutex workerConditionVariableMutex; NzMutex workerConditionVariableMutex;
volatile bool running = true; volatile bool running = true;
unsigned int taskCount; ///TODO: Atomic std::atomic<unsigned int> taskCount;
}; };
TaskSchedulerImpl* s_impl = nullptr; TaskSchedulerImpl* s_impl = nullptr;

View File

@ -54,11 +54,7 @@ NzResource(image),
m_sharedImage(image.m_sharedImage) m_sharedImage(image.m_sharedImage)
{ {
if (m_sharedImage != &emptyImage) if (m_sharedImage != &emptyImage)
{
NazaraMutexLock(m_sharedImage->mutex);
m_sharedImage->refCount++; m_sharedImage->refCount++;
NazaraMutexUnlock(m_sharedImage->mutex);
}
} }
NzImage::NzImage(NzImage&& image) noexcept : NzImage::NzImage(NzImage&& image) noexcept :
@ -1220,11 +1216,7 @@ NzImage& NzImage::operator=(const NzImage& image)
m_sharedImage = image.m_sharedImage; m_sharedImage = image.m_sharedImage;
if (m_sharedImage != &emptyImage) if (m_sharedImage != &emptyImage)
{
NazaraMutexLock(m_sharedImage->mutex);
m_sharedImage->refCount++; m_sharedImage->refCount++;
NazaraMutexUnlock(m_sharedImage->mutex);
}
return *this; return *this;
} }
@ -1294,7 +1286,6 @@ void NzImage::EnsureOwnership()
if (m_sharedImage == &emptyImage) if (m_sharedImage == &emptyImage)
return; return;
NazaraLock(m_sharedImage->mutex);
if (m_sharedImage->refCount > 1) if (m_sharedImage->refCount > 1)
{ {
m_sharedImage->refCount--; m_sharedImage->refCount--;
@ -1316,11 +1307,7 @@ void NzImage::ReleaseImage()
if (m_sharedImage == &emptyImage) if (m_sharedImage == &emptyImage)
return; return;
NazaraMutexLock(m_sharedImage->mutex); if (--m_sharedImage->refCount == 0)
bool freeSharedImage = (--m_sharedImage->refCount == 0);
NazaraMutexUnlock(m_sharedImage->mutex);
if (freeSharedImage)
{ {
for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i) for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i)
delete[] m_sharedImage->pixels[i]; delete[] m_sharedImage->pixels[i];

View File

@ -6,6 +6,7 @@
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Config.hpp> #include <Nazara/Utility/Config.hpp>
#include <algorithm> #include <algorithm>
#include <atomic>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
@ -65,13 +66,17 @@ namespace
struct NzVertexDeclarationImpl struct NzVertexDeclarationImpl
{ {
NzVertexDeclarationImpl() :
refCount(1)
{
}
std::vector<NzVertexElement> elements; std::vector<NzVertexElement> elements;
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1]; int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
int streamPos[nzElementStream_Max+1]; int streamPos[nzElementStream_Max+1];
unsigned int stride[nzElementStream_Max+1] = {0}; unsigned int stride[nzElementStream_Max+1] = {0};
unsigned short refCount = 1; std::atomic_ushort refCount;
NazaraMutex(mutex)
}; };
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount) NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
@ -92,11 +97,7 @@ NzResource(),
m_sharedImpl(declaration.m_sharedImpl) m_sharedImpl(declaration.m_sharedImpl)
{ {
if (m_sharedImpl) if (m_sharedImpl)
{
NazaraMutexLock(m_sharedImpl->mutex);
m_sharedImpl->refCount++; m_sharedImpl->refCount++;
NazaraMutexUnlock(m_sharedImpl->mutex);
}
} }
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept : NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept :
@ -126,7 +127,7 @@ bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int e
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int)); std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int)); std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
// On copie et trie les éléments // On copie et trions les éléments
impl->elements.resize(elementCount); impl->elements.resize(elementCount);
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement)); std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare); std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
@ -177,11 +178,7 @@ void NzVertexDeclaration::Destroy()
NotifyDestroy(); NotifyDestroy();
NazaraMutexLock(m_sharedImpl->mutex); if (--m_sharedImpl->refCount == 0)
bool freeSharedImpl = (--m_sharedImpl->refCount == 0);
NazaraMutexUnlock(m_sharedImpl->mutex);
if (freeSharedImpl)
delete m_sharedImpl; delete m_sharedImpl;
m_sharedImpl = nullptr; m_sharedImpl = nullptr;
@ -374,11 +371,7 @@ NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& d
m_sharedImpl = declaration.m_sharedImpl; m_sharedImpl = declaration.m_sharedImpl;
if (m_sharedImpl) if (m_sharedImpl)
{
NazaraMutexLock(m_sharedImpl->mutex);
m_sharedImpl->refCount++; m_sharedImpl->refCount++;
NazaraMutexUnlock(m_sharedImpl->mutex);
}
return *this; return *this;
} }