Skip to content

Commit

Permalink
Merge pull request #132 from jac3km4/mutex-spin-lock
Browse files Browse the repository at this point in the history
Rename SharedMutex and introduce Mutex
  • Loading branch information
wopss authored Jul 8, 2024
2 parents 665cf36 + 40afa20 commit f172089
Show file tree
Hide file tree
Showing 20 changed files with 306 additions and 148 deletions.
2 changes: 1 addition & 1 deletion include/RED4ext/Buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct DeferredDataBuffer
uint64_t unk48; // 48
uint32_t unk50; // 50
DeferredDataBufferState state; // 54
SharedMutex lock; // 55
SharedSpinLock lock; // 55
uint16_t unk56; // 56
};
RED4EXT_ASSERT_SIZE(DeferredDataBuffer, 0x58);
Expand Down
2 changes: 1 addition & 1 deletion include/RED4ext/GameEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ struct CBaseEngine
int8_t unk34; // 34
uint64_t scriptsTimestamp; // 38
int8_t unk40; // 40
SharedMutex terminationLock; // 41
SharedSpinLock terminationLock; // 41
int32_t unk44; // 44
int8_t terminating; // 48
int8_t unk49; // 49
Expand Down
6 changes: 3 additions & 3 deletions include/RED4ext/Memory/Pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include <RED4ext/Common.hpp>
#include <RED4ext/Hashing/FNV1a.hpp>
#include <RED4ext/SharedMutex.hpp>
#include <RED4ext/SharedSpinLock.hpp>

namespace RED4ext::Memory
{
Expand Down Expand Up @@ -47,7 +47,7 @@ struct PoolRegistry
{
static constexpr auto MaxPoolCount = 768;

SharedMutex nodesLock; // 00
SharedSpinLock nodesLock; // 00
PoolInfo nodes[MaxPoolCount]; // 08

template<typename T = PoolInfo>
Expand All @@ -60,7 +60,7 @@ struct PoolRegistry
template<typename T = PoolInfo>
T* Get(uint32_t aHandle)
{
std::shared_lock<SharedMutex> _(nodesLock);
std::shared_lock<SharedSpinLock> _(nodesLock);

/* Did not find anything to do this in O(1), could do it with some caching, but a separate struct would have to
* be mantained, which is an overkill for this. Code that is using this should cache the value in a static
Expand Down
30 changes: 30 additions & 0 deletions include/RED4ext/Mutex-inl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#ifdef RED4EXT_STATIC_LIB
#include <RED4ext/Mutex.hpp>
#endif

RED4EXT_INLINE RED4ext::Mutex::Mutex()
{
InitializeCriticalSection(&m_cs);
}

RED4EXT_INLINE void RED4ext::Mutex::Lock()
{
EnterCriticalSection(&m_cs);
}

RED4EXT_INLINE void RED4ext::Mutex::Unlock()
{
LeaveCriticalSection(&m_cs);
}

RED4EXT_INLINE void RED4ext::Mutex::lock()
{
Lock();
}

RED4EXT_INLINE void RED4ext::Mutex::unlock()
{
Unlock();
}
34 changes: 34 additions & 0 deletions include/RED4ext/Mutex.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <RED4ext/Common.hpp>
#include <windows.h>

namespace RED4ext
{
struct Mutex
{
Mutex();
Mutex(const Mutex&) = delete;
Mutex(Mutex&&) = delete;
Mutex& operator=(const Mutex&) = delete;
Mutex& operator=(Mutex&&) = delete;

void Lock();
void Unlock();

// --------------------------------------------
// -- support for lock_guard --
// --------------------------------------------

void lock();
void unlock();

private:
CRITICAL_SECTION m_cs;
};
RED4EXT_ASSERT_SIZE(Mutex, 40);
} // namespace RED4ext

#ifdef RED4EXT_HEADER_ONLY
#include <RED4ext/Mutex-inl.hpp>
#endif
2 changes: 2 additions & 0 deletions include/RED4ext/RED4ext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
#include <RED4ext/Scripting/Stack.hpp>
#include <RED4ext/Scripting/Utils.hpp>

#include <RED4ext/Mutex.hpp>
#include <RED4ext/SharedMutex.hpp>
#include <RED4ext/SharedSpinLock.hpp>
#include <RED4ext/TweakDB.hpp>

#include <RED4ext/InstanceType.hpp>
Expand Down
18 changes: 10 additions & 8 deletions include/RED4ext/RTTISystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
#include <Windows.h>
#include <cstdint>

#include <RED4ext/Callback.hpp>
#include <RED4ext/CName.hpp>
#include <RED4ext/Callback.hpp>
#include <RED4ext/Common.hpp>
#include <RED4ext/DynArray.hpp>
#include <RED4ext/HashMap.hpp>
#include <RED4ext/Mutex.hpp>
#include <RED4ext/RTTITypes.hpp>
#include <RED4ext/SharedSpinLock.hpp>

namespace RED4ext
{
Expand Down Expand Up @@ -56,10 +58,10 @@ struct IRTTISystem
// containing the name and the bit.
virtual void InitializeScriptRuntime() = 0; // F8 - Called by script loader at the very end
virtual void RegisterScriptName(CName aNativeName, CName aScriptedName) = 0; // 100
virtual CClass* GetClassByScriptName(CName aName) = 0; // 108
virtual CEnum* GetEnumByScriptName(CName aName) = 0; // 110
virtual CName ConvertNativeToScriptName(CName aName) = 0; // 118
virtual CName ConvertScriptToNativeName(CName aName) = 0; // 120
virtual CClass* GetClassByScriptName(CName aName) = 0; // 108
virtual CEnum* GetEnumByScriptName(CName aName) = 0; // 110
virtual CName ConvertNativeToScriptName(CName aName) = 0; // 118
virtual CName ConvertScriptToNativeName(CName aName) = 0; // 120
virtual CString* GetStringConst(uint32_t aIndex) = 0; // 128 - Used by StringConst opcode (0x10)
virtual void SetStringTable(DynArray<CString>& aStrings) = 0; // 130 - Called by script loader

Expand Down Expand Up @@ -88,9 +90,9 @@ struct CRTTISystem : IRTTISystem
DynArray<CString> strings; // 1B0 - Used by StringConst opcode (0x10)
DynArray<void*> unk1C0; // 1C0
DynArray<void*> unk1D0; // 1D0
CRITICAL_SECTION unk1E0; // 1E0
volatile int8_t typesLock; // 208
CRITICAL_SECTION unk210; // 210
Mutex unk1E0; // 1E0
SharedSpinLock typesLock; // 208
Mutex rttiRegistratorMutex; // 210
};
RED4EXT_ASSERT_SIZE(CRTTISystem, 0x238);
RED4EXT_ASSERT_OFFSET(CRTTISystem, types, 0x10);
Expand Down
173 changes: 126 additions & 47 deletions include/RED4ext/RTTITypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ struct CBaseRTTIType
virtual CName GetComputedName() const; // 30
virtual void Construct(ScriptInstance aMemory) const = 0; // 38
virtual void Destruct(ScriptInstance aMemory) const = 0; // 40
virtual const bool IsEqual(
const ScriptInstance aLhs, const ScriptInstance aRhs,
uint32_t a3 = 0) = 0; // 48 - Not const because CClass aquire some mutex when this is called and a flag is modified.
virtual const bool IsEqual(const ScriptInstance aLhs, const ScriptInstance aRhs,
uint32_t a3 = 0) = 0; // 48 - Not const because CClass aquire some mutex when this is
// called and a flag is modified.
virtual void Assign(ScriptInstance aLhs, const ScriptInstance aRhs) const = 0; // 50
virtual void Move(ScriptInstance aLhs, ScriptInstance aRhs) const; // 58
virtual bool Unserialize(BaseStream* aStream, ScriptInstance aInstance, int64_t a3) const = 0; // 60
Expand Down Expand Up @@ -225,7 +225,7 @@ struct CClass : CBaseRTTIType
int8_t listening[256]; // 1C0 - Bitmask of event types that this class listens to
int16_t eventTypeId; // 2C0 - Assigned to event classes only
int32_t unk2C4; // 2C4
SharedMutex unk2C8; // 2C8
SharedSpinLock unk2C8; // 2C8
uint8_t unk2C9; // 2C9
};
RED4EXT_ASSERT_SIZE(CClass, 0x2D0);
Expand Down Expand Up @@ -594,62 +594,141 @@ RED4EXT_ASSERT_SIZE(CRTTIMultiChannelCurveType, 0x48);
RED4EXT_ASSERT_OFFSET(CRTTIMultiChannelCurveType, name, 0x10);
RED4EXT_ASSERT_OFFSET(CRTTIMultiChannelCurveType, curveType, 0x18);

struct [[deprecated("Use 'CBaseRTTIType' instead.")]] IRTTIType : CBaseRTTIType{};
struct [[deprecated("Use 'CBaseRTTIType' instead.")]] CRTTIBaseType : CBaseRTTIType{};
struct [[deprecated("Use 'CBaseRTTIType' instead.")]] CRTTIType : CBaseRTTIType{};

struct [[deprecated("Use 'CFundamentalRTTITypeBool' instead.")]] BoolType : CFundamentalRTTITypeBool{};
struct [[deprecated("Use 'CFundamentalRTTITypeInt8' instead.")]] Int8Type : CFundamentalRTTITypeInt8{};
struct [[deprecated("Use 'CFundamentalRTTITypeUint8' instead.")]] Uint8Type : CFundamentalRTTITypeUint8{};
struct [[deprecated("Use 'CFundamentalRTTITypeInt16' instead.")]] Int16Type : CFundamentalRTTITypeInt16{};
struct [[deprecated("Use 'CFundamentalRTTITypeUint16' instead.")]] Uint16Type : CFundamentalRTTITypeUint16{};
struct [[deprecated("Use 'CFundamentalRTTITypeInt32' instead.")]] Int32Type : CFundamentalRTTITypeInt32{};
struct [[deprecated("Use 'CFundamentalRTTITypeUint32' instead.")]] Uint32Type : CFundamentalRTTITypeUint32{};
struct [[deprecated("Use 'CFundamentalRTTITypeInt64' instead.")]] Int64Type : CFundamentalRTTITypeInt64{};
struct [[deprecated("Use 'CFundamentalRTTITypeUint64' instead.")]] Uint64Type : CFundamentalRTTITypeUint64{};
struct [[deprecated("Use 'CFundamentalRTTITypeFloat' instead.")]] FloatType : CFundamentalRTTITypeFloat{};
struct [[deprecated("Use 'CFundamentalRTTITypeDouble' instead.")]] DoubleType : CFundamentalRTTITypeDouble{};

struct [[deprecated("Use 'CSimpleRTTITypeCName' instead.")]] CNameType : CSimpleRTTITypeCName{};
struct [[deprecated("Use 'CSimpleRTTITypeString' instead.")]] StringType : CSimpleRTTITypeString{};
struct [[deprecated("Use 'CBaseRTTIType' instead.")]] IRTTIType : CBaseRTTIType
{
};
struct [[deprecated("Use 'CBaseRTTIType' instead.")]] CRTTIBaseType : CBaseRTTIType
{
};
struct [[deprecated("Use 'CBaseRTTIType' instead.")]] CRTTIType : CBaseRTTIType
{
};

struct [[deprecated("Use 'CFundamentalRTTITypeBool' instead.")]] BoolType : CFundamentalRTTITypeBool
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeInt8' instead.")]] Int8Type : CFundamentalRTTITypeInt8
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeUint8' instead.")]] Uint8Type : CFundamentalRTTITypeUint8
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeInt16' instead.")]] Int16Type : CFundamentalRTTITypeInt16
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeUint16' instead.")]] Uint16Type : CFundamentalRTTITypeUint16
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeInt32' instead.")]] Int32Type : CFundamentalRTTITypeInt32
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeUint32' instead.")]] Uint32Type : CFundamentalRTTITypeUint32
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeInt64' instead.")]] Int64Type : CFundamentalRTTITypeInt64
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeUint64' instead.")]] Uint64Type : CFundamentalRTTITypeUint64
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeFloat' instead.")]] FloatType : CFundamentalRTTITypeFloat
{
};
struct [[deprecated("Use 'CFundamentalRTTITypeDouble' instead.")]] DoubleType : CFundamentalRTTITypeDouble
{
};

struct [[deprecated("Use 'CSimpleRTTITypeCName' instead.")]] CNameType : CSimpleRTTITypeCName
{
};
struct [[deprecated("Use 'CSimpleRTTITypeString' instead.")]] StringType : CSimpleRTTITypeString
{
};
struct [[deprecated("Use 'CSimpleRTTITypeLocalizationString' instead.")]] LocalizationStringType
: CSimpleRTTITypeLocalizationString{};
struct [[deprecated("Use 'CSimpleRTTITypeTweakDBID' instead.")]] TweakDBIDType : CSimpleRTTITypeTweakDBID{};
struct [[deprecated("Use 'CSimpleRTTITypeDataBuffer' instead.")]] DataBufferType : CSimpleRTTITypeDataBuffer{};
: CSimpleRTTITypeLocalizationString
{
};
struct [[deprecated("Use 'CSimpleRTTITypeTweakDBID' instead.")]] TweakDBIDType : CSimpleRTTITypeTweakDBID
{
};
struct [[deprecated("Use 'CSimpleRTTITypeDataBuffer' instead.")]] DataBufferType : CSimpleRTTITypeDataBuffer
{
};
struct [[deprecated("Use 'CSimpleRTTITypeSharedDataBuffer' instead.")]] SharedDataBufferType
: CSimpleRTTITypeSharedDataBuffer{};
: CSimpleRTTITypeSharedDataBuffer
{
};
struct [[deprecated(
"Use 'CSimpleRTTITypeSerializationDeferredDataBuffer' instead.")]] serializationDeferredDataBufferType
: CSimpleRTTITypeSerializationDeferredDataBuffer{};
struct [[deprecated("Use 'CSimpleRTTITypeVariant' instead.")]] VariantType : CSimpleRTTITypeVariant{};
struct [[deprecated("Use 'CSimpleRTTITypeCDateTime' instead.")]] CDateTimeType : CSimpleRTTITypeCDateTime{};
struct [[deprecated("Use 'CSimpleRTTITypeCGUID' instead.")]] CGUIDType : CSimpleRTTITypeCGUID{};
struct [[deprecated("Use 'CSimpleRTTITypeCRUID' instead.")]] CRUIDType : CSimpleRTTITypeCRUID{};
struct [[deprecated("Use 'CSimpleRTTITypeCRUIDRef' instead.")]] CRUIDRefType : CSimpleRTTITypeCRUIDRef{};
struct [[deprecated("Use 'CSimpleRTTITypeEditorObjectID' instead.")]] EditorObjectIDType
: CSimpleRTTITypeEditorObjectID{};
: CSimpleRTTITypeSerializationDeferredDataBuffer
{
};
struct [[deprecated("Use 'CSimpleRTTITypeVariant' instead.")]] VariantType : CSimpleRTTITypeVariant
{
};
struct [[deprecated("Use 'CSimpleRTTITypeCDateTime' instead.")]] CDateTimeType : CSimpleRTTITypeCDateTime
{
};
struct [[deprecated("Use 'CSimpleRTTITypeCGUID' instead.")]] CGUIDType : CSimpleRTTITypeCGUID
{
};
struct [[deprecated("Use 'CSimpleRTTITypeCRUID' instead.")]] CRUIDType : CSimpleRTTITypeCRUID
{
};
struct [[deprecated("Use 'CSimpleRTTITypeCRUIDRef' instead.")]] CRUIDRefType : CSimpleRTTITypeCRUIDRef
{
};
struct [[deprecated("Use 'CSimpleRTTITypeEditorObjectID' instead.")]] EditorObjectIDType : CSimpleRTTITypeEditorObjectID
{
};
struct [[deprecated("Use 'CSimpleRTTITypeGamedataLocKeyWrapper' instead.")]] gamedataLocKeyWrapperType
: CSimpleRTTITypeGamedataLocKeyWrapper{};
: CSimpleRTTITypeGamedataLocKeyWrapper
{
};
struct [[deprecated("Use 'CSimpleRTTITypeMessageResourcePath' instead.")]] MessageResourcePathType
: CSimpleRTTITypeMessageResourcePath{};
struct [[deprecated("Use 'CSimpleRTTITypeNodeRef' instead.")]] NodeRefType : CSimpleRTTITypeNodeRef{};
: CSimpleRTTITypeMessageResourcePath
{
};
struct [[deprecated("Use 'CSimpleRTTITypeNodeRef' instead.")]] NodeRefType : CSimpleRTTITypeNodeRef
{
};
struct [[deprecated("Use 'CSimpleRTTITypeRuntimeEntityRef' instead.")]] RuntimeEntityRefType
: CSimpleRTTITypeRuntimeEntityRef{};
: CSimpleRTTITypeRuntimeEntityRef
{
};

struct [[deprecated("Use 'CRTTIBaseArrayType' instead.")]] CArrayBase : CRTTIBaseArrayType{};
struct [[deprecated("Use 'CRTTIArrayType' instead.")]] CArray : CRTTIArrayType{};
struct [[deprecated("Use 'CRTTIStaticArrayType' instead.")]] CStaticArray : CRTTIStaticArrayType{};
struct [[deprecated("Use 'CRTTINativeArrayType' instead.")]] CNativeArray : CRTTINativeArrayType{};
struct [[deprecated("Use 'CRTTIBaseArrayType' instead.")]] CArrayBase : CRTTIBaseArrayType
{
};
struct [[deprecated("Use 'CRTTIArrayType' instead.")]] CArray : CRTTIArrayType
{
};
struct [[deprecated("Use 'CRTTIStaticArrayType' instead.")]] CStaticArray : CRTTIStaticArrayType
{
};
struct [[deprecated("Use 'CRTTINativeArrayType' instead.")]] CNativeArray : CRTTINativeArrayType
{
};

struct [[deprecated("Use 'CRTTIHandleType' instead.")]] CHandle : CRTTIHandleType{};
struct [[deprecated("Use 'CRTTIWeakHandleType' instead.")]] CWeakHandle : CRTTIWeakHandleType{};
struct [[deprecated("Use 'CRTTIResourceReferenceType' instead.")]] CResourceReference : CRTTIResourceReferenceType{};
struct [[deprecated("Use 'CRTTIHandleType' instead.")]] CHandle : CRTTIHandleType
{
};
struct [[deprecated("Use 'CRTTIWeakHandleType' instead.")]] CWeakHandle : CRTTIWeakHandleType
{
};
struct [[deprecated("Use 'CRTTIResourceReferenceType' instead.")]] CResourceReference : CRTTIResourceReferenceType
{
};

struct [[deprecated("Use 'CRTTIResourceAsyncReferenceType' instead.")]] CResourceAsyncReference
: CRTTIResourceAsyncReferenceType{};
: CRTTIResourceAsyncReferenceType
{
};

struct [[deprecated("Use 'CRTTILegacySingleChannelCurveType' instead.")]] CLegacySingleChannelCurve
: CRTTILegacySingleChannelCurveType{};
: CRTTILegacySingleChannelCurveType
{
};
} // namespace RED4ext

#ifdef RED4EXT_HEADER_ONLY
Expand Down
Loading

0 comments on commit f172089

Please sign in to comment.