Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
99 lines
2.6 KiB
C++
99 lines
2.6 KiB
C++
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
|
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <Jolt/Core/NonCopyable.h>
|
|
|
|
JPH_NAMESPACE_BEGIN
|
|
|
|
/// A mutex array protects a number of resources with a limited amount of mutexes.
|
|
/// It uses hashing to find the mutex of a particular object.
|
|
/// The idea is that if the amount of threads is much smaller than the amount of mutexes
|
|
/// that there is a relatively small chance that two different objects map to the same mutex.
|
|
template <class MutexType>
|
|
class MutexArray : public NonCopyable
|
|
{
|
|
public:
|
|
/// Constructor, constructs an empty mutex array that you need to initialize with Init()
|
|
MutexArray() = default;
|
|
|
|
/// Constructor, constructs an array with inNumMutexes entries
|
|
explicit MutexArray(uint inNumMutexes) { Init(inNumMutexes); }
|
|
|
|
/// Destructor
|
|
~MutexArray() { delete [] mMutexStorage; }
|
|
|
|
/// Initialization
|
|
/// @param inNumMutexes The amount of mutexes to allocate
|
|
void Init(uint inNumMutexes)
|
|
{
|
|
JPH_ASSERT(mMutexStorage == nullptr);
|
|
JPH_ASSERT(inNumMutexes > 0 && IsPowerOf2(inNumMutexes));
|
|
|
|
mMutexStorage = new MutexStorage[inNumMutexes];
|
|
mNumMutexes = inNumMutexes;
|
|
}
|
|
|
|
/// Get the number of mutexes that were allocated
|
|
inline uint GetNumMutexes() const
|
|
{
|
|
return mNumMutexes;
|
|
}
|
|
|
|
/// Convert an object index to a mutex index
|
|
inline uint32 GetMutexIndex(uint32 inObjectIndex) const
|
|
{
|
|
Hash<uint32> hasher;
|
|
return hasher(inObjectIndex) & (mNumMutexes - 1);
|
|
}
|
|
|
|
/// Get the mutex belonging to a certain object by index
|
|
inline MutexType & GetMutexByObjectIndex(uint32 inObjectIndex)
|
|
{
|
|
return mMutexStorage[GetMutexIndex(inObjectIndex)].mMutex;
|
|
}
|
|
|
|
/// Get a mutex by index in the array
|
|
inline MutexType & GetMutexByIndex(uint32 inMutexIndex)
|
|
{
|
|
return mMutexStorage[inMutexIndex].mMutex;
|
|
}
|
|
|
|
/// Lock all mutexes
|
|
void LockAll()
|
|
{
|
|
JPH_PROFILE_FUNCTION();
|
|
|
|
MutexStorage *end = mMutexStorage + mNumMutexes;
|
|
for (MutexStorage *m = mMutexStorage; m < end; ++m)
|
|
m->mMutex.lock();
|
|
}
|
|
|
|
/// Unlock all mutexes
|
|
void UnlockAll()
|
|
{
|
|
JPH_PROFILE_FUNCTION();
|
|
|
|
MutexStorage *end = mMutexStorage + mNumMutexes;
|
|
for (MutexStorage *m = mMutexStorage; m < end; ++m)
|
|
m->mMutex.unlock();
|
|
}
|
|
|
|
private:
|
|
/// Align the mutex to a cache line to ensure there is no false sharing (this is platform dependent, we do this to be safe)
|
|
struct alignas(JPH_CACHE_LINE_SIZE) MutexStorage
|
|
{
|
|
JPH_OVERRIDE_NEW_DELETE
|
|
|
|
MutexType mMutex;
|
|
};
|
|
|
|
MutexStorage * mMutexStorage = nullptr;
|
|
uint mNumMutexes = 0;
|
|
};
|
|
|
|
JPH_NAMESPACE_END
|
|
|