From 459c7a4d07fa21683611251dcab7d9409a5b0001 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 3 May 2013 23:12:58 +0200 Subject: [PATCH] Made use of atomic variables In order to replace mutex-protected integer values (Performance improvement) Former-commit-id: d40ed2444111f00dab372f2371fe91cfd9cd2472 --- include/Nazara/Core/Resource.hpp | 7 +-- include/Nazara/Core/String.hpp | 15 +++--- include/Nazara/Utility/Image.hpp | 10 +--- src/Nazara/Core/Resource.cpp | 69 ++++++------------------ src/Nazara/Core/String.cpp | 15 +----- src/Nazara/Core/TaskScheduler.cpp | 3 +- src/Nazara/Utility/Image.cpp | 15 +----- src/Nazara/Utility/VertexDeclaration.cpp | 25 ++++----- 8 files changed, 41 insertions(+), 118 deletions(-) diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index f1ac2f761..45acbdc64 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -8,6 +8,7 @@ #define NAZARA_RESOURCE_HPP #include +#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE @@ -52,7 +53,7 @@ class NAZARA_API NzResource bool RemoveResourceListener(NzResourceListener* listener) const; bool RemoveResourceReference() const; - void SetPersistent(bool persistent = true, bool checkReferenceCount = false); + bool SetPersistent(bool persistent = true, bool checkReferenceCount = false); protected: void NotifyCreated(); @@ -67,8 +68,8 @@ class NAZARA_API NzResource mutable std::set m_resourceListeners; mutable std::set m_resourceListenersCache; mutable bool m_resourceListenerUpdated; - bool m_resourcePersistent; - mutable unsigned int m_resourceReferenceCount; + std::atomic_bool m_resourcePersistent; + mutable std::atomic_uint m_resourceReferenceCount; }; #endif // NAZARA_RESOURCE_HPP diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index dd1622d56..1b9d6d0fc 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -9,16 +9,11 @@ #include #include +#include #include #include #include -#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_STRING -#include -#else -#include -#endif - class NzAbstractHash; class NzHashDigest; @@ -282,7 +277,10 @@ class NAZARA_API NzString : public NzHashable struct NAZARA_API SharedString { - SharedString() = default; + SharedString() : + refCount(1) + { + } SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) : capacity(bufferSize), @@ -296,8 +294,7 @@ class NAZARA_API NzString : public NzHashable unsigned int size; char* string; - unsigned short refCount = 1; - NazaraMutex(mutex) + std::atomic_ushort refCount; }; static SharedString emptyString; diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index dc9dec4d0..8eb235807 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -19,12 +19,7 @@ #include #include #include - -#if NAZARA_UTILITY_THREADSAFE && NAZARA_THREADSAFETY_IMAGE -#include -#else -#include -#endif +#include ///TODO: Filtres @@ -137,8 +132,7 @@ class NAZARA_API NzImage : public NzResource unsigned int height; unsigned int width; - unsigned short refCount = 1; - NazaraMutex(mutex) + std::atomic_ushort refCount; }; static SharedImage emptyImage; diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 14b89dff5..ead8fb8f6 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -17,7 +17,7 @@ m_resourceReferenceCount(0) } NzResource::NzResource(const NzResource& resource) : -m_resourcePersistent(resource.m_resourcePersistent), +m_resourcePersistent(resource.m_resourcePersistent.load()), m_resourceReferenceCount(0) { } @@ -49,22 +49,16 @@ void NzResource::AddResourceListener(NzResourceListener* listener, int index) co void NzResource::AddResourceReference() const { - NazaraLock(m_mutex) - m_resourceReferenceCount++; } unsigned int NzResource::GetResourceReferenceCount() const { - NazaraLock(m_mutex) - return m_resourceReferenceCount; } bool NzResource::IsPersistent() const { - NazaraLock(m_mutex) - return m_resourcePersistent; } @@ -77,34 +71,11 @@ bool NzResource::RemoveResourceListener(NzResourceListener* listener) const else NazaraError(NzString::Pointer(listener) + " is not a listener of " + NzString::Pointer(this)); - // 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; - } + return RemoveResourceReference(); } bool NzResource::RemoveResourceReference() const { - NazaraMutexLock(m_mutex); - #if NAZARA_CORE_SAFE if (m_resourceReferenceCount == 0) { @@ -115,34 +86,26 @@ bool NzResource::RemoveResourceReference() const 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; return true; } else - { - NazaraMutexUnlock(m_mutex); - 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() diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 10c4bbce3..19e909db6 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -136,11 +136,7 @@ NzString::NzString(const NzString& string) : m_sharedString(string.m_sharedString) { if (m_sharedString != &emptyString) - { - NazaraMutexLock(m_sharedString->mutex); m_sharedString->refCount++; - NazaraMutexUnlock(m_sharedString->mutex); - } } NzString::NzString(NzString&& string) noexcept : @@ -4237,11 +4233,7 @@ NzString& NzString::operator=(const NzString& string) m_sharedString = string.m_sharedString; if (m_sharedString != &emptyString) - { - NazaraMutexLock(m_sharedString->mutex); m_sharedString->refCount++; - NazaraMutexUnlock(m_sharedString->mutex); - } return *this; } @@ -5091,7 +5083,6 @@ void NzString::EnsureOwnership() if (m_sharedString == &emptyString) return; - NazaraLock(m_sharedString->mutex); if (m_sharedString->refCount > 1) { m_sharedString->refCount--; @@ -5115,11 +5106,7 @@ void NzString::ReleaseString() if (m_sharedString == &emptyString) return; - NazaraMutexLock(m_sharedString->mutex); - bool freeSharedString = (--m_sharedString->refCount == 0); - NazaraMutexUnlock(m_sharedString->mutex); - - if (freeSharedString) + if (--m_sharedString->refCount == 0) { delete[] m_sharedString->string; delete m_sharedString; diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index 653a77405..74a4d549f 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ namespace NzMutex waiterConditionVariableMutex; NzMutex workerConditionVariableMutex; volatile bool running = true; - unsigned int taskCount; ///TODO: Atomic + std::atomic taskCount; }; TaskSchedulerImpl* s_impl = nullptr; diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index f5418bc9b..9aba4e4d0 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -54,11 +54,7 @@ NzResource(image), m_sharedImage(image.m_sharedImage) { if (m_sharedImage != &emptyImage) - { - NazaraMutexLock(m_sharedImage->mutex); m_sharedImage->refCount++; - NazaraMutexUnlock(m_sharedImage->mutex); - } } NzImage::NzImage(NzImage&& image) noexcept : @@ -1220,11 +1216,7 @@ NzImage& NzImage::operator=(const NzImage& image) m_sharedImage = image.m_sharedImage; if (m_sharedImage != &emptyImage) - { - NazaraMutexLock(m_sharedImage->mutex); m_sharedImage->refCount++; - NazaraMutexUnlock(m_sharedImage->mutex); - } return *this; } @@ -1294,7 +1286,6 @@ void NzImage::EnsureOwnership() if (m_sharedImage == &emptyImage) return; - NazaraLock(m_sharedImage->mutex); if (m_sharedImage->refCount > 1) { m_sharedImage->refCount--; @@ -1316,11 +1307,7 @@ void NzImage::ReleaseImage() if (m_sharedImage == &emptyImage) return; - NazaraMutexLock(m_sharedImage->mutex); - bool freeSharedImage = (--m_sharedImage->refCount == 0); - NazaraMutexUnlock(m_sharedImage->mutex); - - if (freeSharedImage) + if (--m_sharedImage->refCount == 0) { for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i) delete[] m_sharedImage->pixels[i]; diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index afae5de28..6cc0ca025 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -65,13 +66,17 @@ namespace struct NzVertexDeclarationImpl { + NzVertexDeclarationImpl() : + refCount(1) + { + } + std::vector elements; int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1]; int streamPos[nzElementStream_Max+1]; unsigned int stride[nzElementStream_Max+1] = {0}; - unsigned short refCount = 1; - NazaraMutex(mutex) + std::atomic_ushort refCount; }; NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount) @@ -92,11 +97,7 @@ NzResource(), m_sharedImpl(declaration.m_sharedImpl) { if (m_sharedImpl) - { - NazaraMutexLock(m_sharedImpl->mutex); m_sharedImpl->refCount++; - NazaraMutexUnlock(m_sharedImpl->mutex); - } } 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->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); std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement)); std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare); @@ -177,11 +178,7 @@ void NzVertexDeclaration::Destroy() NotifyDestroy(); - NazaraMutexLock(m_sharedImpl->mutex); - bool freeSharedImpl = (--m_sharedImpl->refCount == 0); - NazaraMutexUnlock(m_sharedImpl->mutex); - - if (freeSharedImpl) + if (--m_sharedImpl->refCount == 0) delete m_sharedImpl; m_sharedImpl = nullptr; @@ -374,11 +371,7 @@ NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& d m_sharedImpl = declaration.m_sharedImpl; if (m_sharedImpl) - { - NazaraMutexLock(m_sharedImpl->mutex); m_sharedImpl->refCount++; - NazaraMutexUnlock(m_sharedImpl->mutex); - } return *this; }