diff --git a/Source/Engine/Platform/ReadWriteLock.h b/Source/Engine/Platform/ReadWriteLock.h new file mode 100644 index 000000000..5386e6ab3 --- /dev/null +++ b/Source/Engine/Platform/ReadWriteLock.h @@ -0,0 +1,15 @@ +// Copyright (c) Wojciech Figat. All rights reserved. + +#pragma once + +#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT +#include "Win32/Win32ReadWriteLock.h" +#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC || PLATFORM_IOS +#include "Unix/UnixReadWriteLock.h" +#elif PLATFORM_SWITCH +#include "Platforms/Switch/Engine/Platform/SwitchReadWriteLock.h" +#else +#error Missing Read Write Lock implementation! +#endif + +#include "Types.h" diff --git a/Source/Engine/Platform/Types.h b/Source/Engine/Platform/Types.h index 50af4279c..79fe02efc 100644 --- a/Source/Engine/Platform/Types.h +++ b/Source/Engine/Platform/Types.h @@ -8,6 +8,8 @@ class WindowsClipboard; typedef WindowsClipboard Clipboard; class Win32CriticalSection; typedef Win32CriticalSection CriticalSection; +class Win32ReadWriteLock; +typedef Win32ReadWriteLock ReadWriteLock; class Win32ConditionVariable; typedef Win32ConditionVariable ConditionVariable; class WindowsFileSystem; @@ -33,6 +35,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class Win32CriticalSection; typedef Win32CriticalSection CriticalSection; +class Win32ReadWriteLock; +typedef Win32ReadWriteLock ReadWriteLock; class Win32ConditionVariable; typedef Win32ConditionVariable ConditionVariable; class UWPFileSystem; @@ -58,6 +62,8 @@ class LinuxClipboard; typedef LinuxClipboard Clipboard; class UnixCriticalSection; typedef UnixCriticalSection CriticalSection; +class UnixReadWriteLock; +typedef UnixReadWriteLock ReadWriteLock; class UnixConditionVariable; typedef UnixConditionVariable ConditionVariable; class LinuxFileSystem; @@ -83,6 +89,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class UnixCriticalSection; typedef UnixCriticalSection CriticalSection; +class UnixReadWriteLock; +typedef UnixReadWriteLock ReadWriteLock; class UnixConditionVariable; typedef UnixConditionVariable ConditionVariable; class PS4FileSystem; @@ -108,6 +116,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class UnixCriticalSection; typedef UnixCriticalSection CriticalSection; +class UnixReadWriteLock; +typedef UnixReadWriteLock ReadWriteLock; class UnixConditionVariable; typedef UnixConditionVariable ConditionVariable; class PS5FileSystem; @@ -133,6 +143,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class Win32CriticalSection; typedef Win32CriticalSection CriticalSection; +class Win32ReadWriteLock; +typedef Win32ReadWriteLock ReadWriteLock; class Win32ConditionVariable; typedef Win32ConditionVariable ConditionVariable; class XboxOneFileSystem; @@ -158,6 +170,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class Win32CriticalSection; typedef Win32CriticalSection CriticalSection; +class Win32ReadWriteLock; +typedef Win32ReadWriteLock ReadWriteLock; class Win32ConditionVariable; typedef Win32ConditionVariable ConditionVariable; class XboxScarlettFileSystem; @@ -183,6 +197,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class UnixCriticalSection; typedef UnixCriticalSection CriticalSection; +class UnixReadWriteLock; +typedef UnixReadWriteLock ReadWriteLock; class UnixConditionVariable; typedef UnixConditionVariable ConditionVariable; class AndroidFileSystem; @@ -208,6 +224,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class SwitchCriticalSection; typedef SwitchCriticalSection CriticalSection; +class SwitchReadWriteLock; +typedef SwitchReadWriteLock ReadWriteLock; class SwitchConditionVariable; typedef SwitchConditionVariable ConditionVariable; class SwitchFileSystem; @@ -233,6 +251,8 @@ class MacClipboard; typedef MacClipboard Clipboard; class UnixCriticalSection; typedef UnixCriticalSection CriticalSection; +class UnixReadWriteLock; +typedef UnixReadWriteLock ReadWriteLock; class UnixConditionVariable; typedef UnixConditionVariable ConditionVariable; class MacFileSystem; @@ -258,6 +278,8 @@ class ClipboardBase; typedef ClipboardBase Clipboard; class UnixCriticalSection; typedef UnixCriticalSection CriticalSection; +class UnixReadWriteLock; +typedef UnixReadWriteLock ReadWriteLock; class UnixConditionVariable; typedef UnixConditionVariable ConditionVariable; class iOSFileSystem; diff --git a/Source/Engine/Platform/Unix/UnixReadWriteLock.h b/Source/Engine/Platform/Unix/UnixReadWriteLock.h new file mode 100644 index 000000000..368e814dc --- /dev/null +++ b/Source/Engine/Platform/Unix/UnixReadWriteLock.h @@ -0,0 +1,71 @@ +// Copyright (c) Wojciech Figat. All rights reserved. + +#pragma once + +#if PLATFORM_UNIX + +#include "Engine/Platform/Platform.h" +#include + +/// +/// Unix implementation of a read/write lock that allows for shared reading by multiple threads and exclusive writing by a single thread. +/// +class FLAXENGINE_API UnixReadWriteLock +{ +private: + mutable pthread_rwlock_t _lock; + +private: + NON_COPYABLE(UnixReadWriteLock); + +public: + /// + /// Initializes a new instance of the class. + /// + UnixReadWriteLock() + { + pthread_rwlock_init(&_lock, nullptr); + } + + /// + /// Finalizes an instance of the class. + /// + ~UnixReadWriteLock() + { + pthread_rwlock_destroy(&_lock); + } + +public: + /// + /// Locks for shared reading. + /// + void ReadLock() const + { + pthread_rwlock_rdlock(&_lock); + } + + /// + /// Releases the lock after shared reading. + /// + void ReadUnlock() const + { + pthread_rwlock_unlock(&_lock); + } + /// + /// Locks for exclusive writing. + /// + void WriteLock() const + { + pthread_rwlock_wrlock(&_lock); + } + + /// + /// Releases the lock after exclusive writing. + /// + void WriteUnlock() const + { + pthread_rwlock_unlock(&_lock); + } +}; + +#endif diff --git a/Source/Engine/Platform/Win32/Win32ReadWriteLock.h b/Source/Engine/Platform/Win32/Win32ReadWriteLock.h new file mode 100644 index 000000000..94bcdd5e3 --- /dev/null +++ b/Source/Engine/Platform/Win32/Win32ReadWriteLock.h @@ -0,0 +1,69 @@ +// Copyright (c) Wojciech Figat. All rights reserved. + +#pragma once + +#if PLATFORM_WIN32 + +#include "WindowsMinimal.h" + +/// +/// Win32 implementation of a read/write lock that allows for shared reading by multiple threads and exclusive writing by a single thread. +/// +class FLAXENGINE_API Win32ReadWriteLock +{ +private: + mutable Windows::SRWLOCK _lock; + +private: + NON_COPYABLE(Win32ReadWriteLock); + +public: + /// + /// Initializes a new instance of the class. + /// + Win32ReadWriteLock() + { + Windows::InitializeSRWLock(&_lock); + } + + /// + /// Finalizes an instance of the class. + /// + ~Win32ReadWriteLock() + { + } + +public: + /// + /// Locks for shared reading. + /// + __forceinline void ReadLock() const + { + Windows::AcquireSRWLockShared(&_lock); + } + + /// + /// Releases the lock after shared reading. + /// + __forceinline void ReadUnlock() const + { + Windows::ReleaseSRWLockShared(&_lock); + } + /// + /// Locks for exclusive writing. + /// + __forceinline void WriteLock() const + { + Windows::AcquireSRWLockExclusive(&_lock); + } + + /// + /// Releases the lock after exclusive writing. + /// + __forceinline void WriteUnlock() const + { + Windows::ReleaseSRWLockExclusive(&_lock); + } +}; + +#endif diff --git a/Source/Engine/Platform/Win32/WindowsMinimal.h b/Source/Engine/Platform/Win32/WindowsMinimal.h index 04a595e72..137b6195e 100644 --- a/Source/Engine/Platform/Win32/WindowsMinimal.h +++ b/Source/Engine/Platform/Win32/WindowsMinimal.h @@ -65,6 +65,11 @@ namespace Windows void* Ptr; }; + struct SRWLOCK + { + void* Ptr; + }; + struct OVERLAPPED { void* Data1[3]; @@ -96,6 +101,12 @@ namespace Windows WIN_API void WIN_API_CALLCONV WakeConditionVariable(CONDITION_VARIABLE* ConditionVariable); WIN_API void WIN_API_CALLCONV WakeAllConditionVariable(CONDITION_VARIABLE* ConditionVariable); + WIN_API void WIN_API_CALLCONV InitializeSRWLock(SRWLOCK* SRWLock); + WIN_API void WIN_API_CALLCONV AcquireSRWLockShared(SRWLOCK* SRWLock); + WIN_API void WIN_API_CALLCONV ReleaseSRWLockShared(SRWLOCK* SRWLock); + WIN_API void WIN_API_CALLCONV AcquireSRWLockExclusive(SRWLOCK* SRWLock); + WIN_API void WIN_API_CALLCONV ReleaseSRWLockExclusive(SRWLOCK* SRWLock); + class IDataObject; typedef GUID IID;