实现基本内存操作 Linux 平台测试
This commit is contained in:
parent
7361a673e4
commit
f53211ef50
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,5 +2,4 @@
|
|||||||
.vs/
|
.vs/
|
||||||
|
|
||||||
# CMake generated files
|
# CMake generated files
|
||||||
Build/
|
out/
|
||||||
Install/
|
|
||||||
|
@ -4,12 +4,33 @@
|
|||||||
"name": "x64-Debug",
|
"name": "x64-Debug",
|
||||||
"generator": "Ninja",
|
"generator": "Ninja",
|
||||||
"configurationType": "Debug",
|
"configurationType": "Debug",
|
||||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||||
"buildRoot": "${projectDir}\\Build\\${name}",
|
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||||
"installRoot": "${projectDir}\\Install\\${name}",
|
|
||||||
"cmakeCommandArgs": "",
|
"cmakeCommandArgs": "",
|
||||||
"buildCommandArgs": "",
|
"buildCommandArgs": "",
|
||||||
"ctestCommandArgs": ""
|
"ctestCommandArgs": "",
|
||||||
|
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||||
|
"variables": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Linux-GCC-Debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"configurationType": "Debug",
|
||||||
|
"cmakeExecutable": "cmake",
|
||||||
|
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
|
||||||
|
"cmakeCommandArgs": "-D CMAKE_C_COMPILER=gcc-10 -D CMAKE_CXX_COMPILER=g++-10",
|
||||||
|
"buildCommandArgs": "",
|
||||||
|
"ctestCommandArgs": "",
|
||||||
|
"inheritEnvironments": [ "linux_x64" ],
|
||||||
|
"remoteMachineName": "${defaultRemoteMachineName}",
|
||||||
|
"remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src",
|
||||||
|
"remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}",
|
||||||
|
"remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}",
|
||||||
|
"remoteCopySources": true,
|
||||||
|
"rsyncCommandArgs": "-t --delete --delete-excluded",
|
||||||
|
"remoteCopyBuildOutput": false,
|
||||||
|
"remoteCopySourcesMethod": "rsync",
|
||||||
|
"variables": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
75
Redcraft.Core/Source/Private/HAL/Memory.cpp
Normal file
75
Redcraft.Core/Source/Private/HAL/Memory.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "HAL/Memory.h"
|
||||||
|
|
||||||
|
#include "Templates/Alignment.h"
|
||||||
|
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
#include <corecrt_malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_REDCRAFT_BEGIN
|
||||||
|
NS_BEGIN(Memory)
|
||||||
|
|
||||||
|
void* Malloc(size_t Count, uint32 Alignment)
|
||||||
|
{
|
||||||
|
Alignment = Math::Max(Count >= 16 ? (uint32)16 : (uint32)8, Alignment);
|
||||||
|
|
||||||
|
void* Result = nullptr;
|
||||||
|
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
if (Count != 0) Result = _aligned_malloc(Count, Alignment);
|
||||||
|
#else
|
||||||
|
void* Ptr = SystemMalloc(Count + Alignment + sizeof(void*) + sizeof(size_t));
|
||||||
|
if (Ptr)
|
||||||
|
{
|
||||||
|
Result = Align((uint8*)Ptr + sizeof(void*) + sizeof(size_t), Alignment);
|
||||||
|
*((void**)((uint8*)Result - sizeof(void*))) = Ptr;
|
||||||
|
*((size_t*)((uint8*)Result - sizeof(void*) - sizeof(size_t))) = Count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Realloc(void* Ptr, size_t Count, uint32 Alignment)
|
||||||
|
{
|
||||||
|
Alignment = Math::Max(Count >= 16 ? (uint32)16 : (uint32)8, Alignment);
|
||||||
|
|
||||||
|
if (Ptr && Count)
|
||||||
|
{
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
return _aligned_realloc(Ptr, Count, Alignment);
|
||||||
|
#else
|
||||||
|
void* Result = Malloc(Count, Alignment);
|
||||||
|
size_t PtrSize = *((size_t*)((uint8*)Ptr - sizeof(void*) - sizeof(size_t)));
|
||||||
|
Memcpy(Result, Ptr, Math::Min(Count, PtrSize));
|
||||||
|
Free(Ptr);
|
||||||
|
return Result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (Ptr == nullptr)
|
||||||
|
{
|
||||||
|
return Malloc(Count, Alignment);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Free(Ptr);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free(void* Ptr)
|
||||||
|
{
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
_aligned_free(Ptr);
|
||||||
|
#else
|
||||||
|
SystemFree(*((void**)((uint8*)Ptr - sizeof(void*))));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t QuantizeSize(size_t Count, uint32 Alignment)
|
||||||
|
{
|
||||||
|
return Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_END(Memory)
|
||||||
|
NS_REDCRAFT_END
|
43
Redcraft.Core/Source/Public/HAL/Memory.h
Normal file
43
Redcraft.Core/Source/Public/HAL/Memory.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreTypes.h"
|
||||||
|
|
||||||
|
NS_REDCRAFT_BEGIN
|
||||||
|
NS_BEGIN(Memory)
|
||||||
|
|
||||||
|
constexpr uint32 DEFAULT_ALIGNMENT = 0;
|
||||||
|
constexpr uint32 MIN_ALIGNMENT = 8;
|
||||||
|
|
||||||
|
FORCEINLINE void* Memmove(void* Dest, const void* Src, size_t Count);
|
||||||
|
FORCEINLINE int32 Memcmp(const void* Buf1, const void* Buf2, size_t Count);
|
||||||
|
FORCEINLINE void Memset(void* Dest, uint8 ValueToSet, size_t Count);
|
||||||
|
FORCEINLINE void* Memzero(void* Dest, size_t Count);
|
||||||
|
FORCEINLINE void* Memcpy(void* Dest, const void* Src, size_t Count);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static FORCEINLINE void Memset(T& Src, uint8 ValueToSet);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static FORCEINLINE void Memzero(T& Src);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static FORCEINLINE void Memcpy(T& Dest, const T& Src);
|
||||||
|
|
||||||
|
FORCEINLINE void* SystemMalloc(size_t Count);
|
||||||
|
FORCEINLINE void SystemFree(void* Ptr);
|
||||||
|
|
||||||
|
REDCRAFTCORE_API void* Malloc(size_t Count, uint32 Alignment = DEFAULT_ALIGNMENT);
|
||||||
|
REDCRAFTCORE_API void* Realloc(void* Ptr, size_t Count, uint32 Alignment = DEFAULT_ALIGNMENT);
|
||||||
|
REDCRAFTCORE_API void Free(void* Ptr);
|
||||||
|
REDCRAFTCORE_API size_t QuantizeSize(size_t Count, uint32 Alignment = DEFAULT_ALIGNMENT);
|
||||||
|
|
||||||
|
NS_END(Memory)
|
||||||
|
NS_REDCRAFT_END
|
||||||
|
|
||||||
|
#include "HAL/Memory.inl"
|
||||||
|
|
||||||
|
void* operator new(std::size_t Count) { return NS_REDCRAFT::Memory::Malloc(Count); };
|
||||||
|
void* operator new(std::size_t Count, std::align_val_t Alignment) { return NS_REDCRAFT::Memory::Malloc(Count, (NS_REDCRAFT::uint32)Alignment); };
|
||||||
|
|
||||||
|
void operator delete(void* Ptr) noexcept { NS_REDCRAFT::Memory::Free(Ptr); }
|
||||||
|
void operator delete(void* Ptr, std::align_val_t Alignment) noexcept { NS_REDCRAFT::Memory::Free(Ptr); }
|
67
Redcraft.Core/Source/Public/HAL/Memory.inl
Normal file
67
Redcraft.Core/Source/Public/HAL/Memory.inl
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "Math/MathUtility.h"
|
||||||
|
#include "Templates/TypeTraits.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
NS_REDCRAFT_BEGIN
|
||||||
|
NS_BEGIN(Memory)
|
||||||
|
|
||||||
|
void* Memmove(void* Dest, const void* Src, size_t Count)
|
||||||
|
{
|
||||||
|
return std::memmove(Dest, Src, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 Memcmp(const void* Buf1, const void* Buf2, size_t Count)
|
||||||
|
{
|
||||||
|
return std::memcmp(Buf1, Buf2, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Memset(void* Dest, uint8 ValueToSet, size_t Count)
|
||||||
|
{
|
||||||
|
std::memset(Dest, ValueToSet, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Memzero(void* Dest, size_t Count)
|
||||||
|
{
|
||||||
|
return std::memset(Dest, 0, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Memcpy(void* Dest, const void* Src, size_t Count)
|
||||||
|
{
|
||||||
|
return std::memcpy(Dest, Src, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static FORCEINLINE void Memset(T& Src, uint8 ValueToSet)
|
||||||
|
{
|
||||||
|
static_assert(!TypeTraits::TIsPointer<T>::Value, "For pointers use the three parameters function");
|
||||||
|
Memset(&Src, ValueToSet, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static FORCEINLINE void Memzero(T& Src)
|
||||||
|
{
|
||||||
|
static_assert(!TypeTraits::TIsPointer<T>::Value, "For pointers use the two parameters function");
|
||||||
|
Memzero(&Src, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static FORCEINLINE void Memcpy(T& Dest, const T& Src)
|
||||||
|
{
|
||||||
|
static_assert(!TypeTraits::TIsPointer<T>::Value, "For pointers use the three parameters function");
|
||||||
|
Memcpy(&Dest, &Src, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* SystemMalloc(size_t Count)
|
||||||
|
{
|
||||||
|
return std::malloc(Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemFree(void* Ptr)
|
||||||
|
{
|
||||||
|
std::free(Ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_END(Memory)
|
||||||
|
NS_REDCRAFT_END
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Misc/CoreDefines.h"
|
#include "Misc/CoreDefines.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -46,6 +47,8 @@ NS_REDCRAFT_BEGIN
|
|||||||
|
|
||||||
// Alignment.
|
// Alignment.
|
||||||
|
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
|
||||||
#define GCC_PACK(n) __attribute__((packed,aligned(n)))
|
#define GCC_PACK(n) __attribute__((packed,aligned(n)))
|
||||||
@ -63,6 +66,20 @@ NS_REDCRAFT_BEGIN
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#elif PLATFORM_LINUX
|
||||||
|
|
||||||
|
#define GCC_PACK(n) __attribute__((packed,aligned(n)))
|
||||||
|
#define GCC_ALIGN(n) __attribute__((aligned(n)))
|
||||||
|
#define MS_ALIGN(n)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GCC_PACK(n)
|
||||||
|
#define GCC_ALIGN(n)
|
||||||
|
#define MS_ALIGN(n)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// DLL export and import definitions.
|
// DLL export and import definitions.
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
@ -114,10 +131,6 @@ typedef intptr_t ssize_t;
|
|||||||
typedef decltype(NULL) null_t;
|
typedef decltype(NULL) null_t;
|
||||||
typedef std::nullptr_t nullptr_t;
|
typedef std::nullptr_t nullptr_t;
|
||||||
|
|
||||||
// Alignment.
|
|
||||||
|
|
||||||
typedef std::max_align_t max_align_t;
|
|
||||||
|
|
||||||
#if PLATFORM_LINUX
|
#if PLATFORM_LINUX
|
||||||
#define PLATFORM_TCHAR_IS_CHAR16 1
|
#define PLATFORM_TCHAR_IS_CHAR16 1
|
||||||
#else
|
#else
|
||||||
|
33
Redcraft.Core/Source/Public/Math/MathUtility.h
Normal file
33
Redcraft.Core/Source/Public/Math/MathUtility.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreTypes.h"
|
||||||
|
|
||||||
|
NS_REDCRAFT_BEGIN
|
||||||
|
NS_BEGIN(Math)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr FORCEINLINE T Abs(const T A)
|
||||||
|
{
|
||||||
|
return (A >= (T)0) ? A : -A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr FORCEINLINE T Sign(const T A)
|
||||||
|
{
|
||||||
|
return (A > (T)0) ? (T)1 : ((A < (T)0) ? (T)-1 : (T)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr FORCEINLINE T Max(const T A, const T B)
|
||||||
|
{
|
||||||
|
return (A >= B) ? A : B;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr FORCEINLINE T Min(const T A, const T B)
|
||||||
|
{
|
||||||
|
return (A <= B) ? A : B;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_END(Math)
|
||||||
|
NS_REDCRAFT_END
|
@ -9,6 +9,10 @@
|
|||||||
#define NS_REDCRAFT_END NS_END(NS_REDCRAFT)
|
#define NS_REDCRAFT_END NS_END(NS_REDCRAFT)
|
||||||
#define NS_REDCRAFT_USING NS_USING(NS_REDCRAFT)
|
#define NS_REDCRAFT_USING NS_USING(NS_REDCRAFT)
|
||||||
|
|
||||||
|
#define NS_PRIVATE Private
|
||||||
|
#define NS_PRIVATE_BEGIN NS_BEGIN(NS_PRIVATE)
|
||||||
|
#define NS_PRIVATE_END NS_END(NS_PRIVATE)
|
||||||
|
|
||||||
#define NS_STD_BEGIN NS_BEGIN(std)
|
#define NS_STD_BEGIN NS_BEGIN(std)
|
||||||
#define NS_STD_END NS_END(std)
|
#define NS_STD_END NS_END(std)
|
||||||
#define NS_STD_USING NS_USING(std)
|
#define NS_STD_USING NS_USING(std)
|
||||||
|
44
Redcraft.Core/Source/Public/Templates/Alignment.h
Normal file
44
Redcraft.Core/Source/Public/Templates/Alignment.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreTypes.h"
|
||||||
|
#include "Templates/TypeTraits.h"
|
||||||
|
|
||||||
|
NS_REDCRAFT_BEGIN
|
||||||
|
NS_BEGIN(Memory)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCEINLINE constexpr T Align(T Val, uint64 Alignment)
|
||||||
|
{
|
||||||
|
static_assert(TypeTraits::TIsIntegral<T>::Value || TypeTraits::TIsPointer<T>::Value, "Align expects an integer or pointer type");
|
||||||
|
|
||||||
|
return (T)(((uint64)Val + Alignment - 1) & ~(Alignment - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCEINLINE constexpr T AlignDown(T Val, uint64 Alignment)
|
||||||
|
{
|
||||||
|
static_assert(TypeTraits::TIsIntegral<T>::Value || TypeTraits::TIsPointer<T>::Value, "AlignDown expects an integer or pointer type");
|
||||||
|
|
||||||
|
return (T)(((uint64)Val) & ~(Alignment - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCEINLINE constexpr bool IsAligned(T Val, uint64 Alignment)
|
||||||
|
{
|
||||||
|
static_assert(TypeTraits::TIsIntegral<T>::Value || TypeTraits::TIsPointer<T>::Value, "IsAligned expects an integer or pointer type");
|
||||||
|
|
||||||
|
return !((uint64)Val & (Alignment - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCEINLINE constexpr T AlignArbitrary(T Val, uint64 Alignment)
|
||||||
|
{
|
||||||
|
static_assert(TypeTraits::TIsIntegral<T>::Value || TypeTraits::TIsPointer<T>::Value, "AlignArbitrary expects an integer or pointer type");
|
||||||
|
|
||||||
|
return (T)((((uint64)Val + Alignment - 1) / Alignment) * Alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_END(Memory)
|
||||||
|
NS_REDCRAFT_END
|
@ -84,7 +84,6 @@ template <typename T, size_t N = 0> struct TExtent { static constexpr size_t Val
|
|||||||
template <typename T, typename U> struct TIsSame { static constexpr bool Value = std::is_same_v<T, U>; };
|
template <typename T, typename U> struct TIsSame { static constexpr bool Value = std::is_same_v<T, U>; };
|
||||||
template <typename T, typename U> struct TIsBaseOf { static constexpr bool Value = std::is_base_of_v<T, U>; };
|
template <typename T, typename U> struct TIsBaseOf { static constexpr bool Value = std::is_base_of_v<T, U>; };
|
||||||
template <typename T, typename U> struct TIsConvertible { static constexpr bool Value = std::is_convertible_v<T, U>; };
|
template <typename T, typename U> struct TIsConvertible { static constexpr bool Value = std::is_convertible_v<T, U>; };
|
||||||
template <typename T, typename U> struct TIsLayoutCompatible { static constexpr bool Value = std::is_layout_compatible_v<T, U>; };
|
|
||||||
template <typename Func, typename... ArgTypes> struct TIsInvocable { static constexpr bool Value = std::is_invocable_v<Func, ArgTypes...>; };
|
template <typename Func, typename... ArgTypes> struct TIsInvocable { static constexpr bool Value = std::is_invocable_v<Func, ArgTypes...>; };
|
||||||
template <typename Result, typename Func, typename... ArgTypes> struct TIsInvocableResult { static constexpr bool Value = std::is_invocable_r_v<Result, Func, ArgTypes...>; };
|
template <typename Result, typename Func, typename... ArgTypes> struct TIsInvocableResult { static constexpr bool Value = std::is_invocable_r_v<Result, Func, ArgTypes...>; };
|
||||||
|
|
||||||
@ -120,7 +119,7 @@ template <typename T> struct TRemoveAllExtents { typedef typename std::remove_al
|
|||||||
|
|
||||||
// Miscellaneous transformations
|
// Miscellaneous transformations
|
||||||
|
|
||||||
template <size_t Len, size_t Align = alignof(max_align_t)> struct TAlignedStorage { typedef typename std::aligned_storage_t<Len, Align> Type; };
|
template <size_t Len, size_t Alignment> struct TAlignedStorage { typedef typename std::aligned_storage_t<Len, Alignment> Type; };
|
||||||
template <size_t Len, typename... Types> struct TAlignedUnion { typedef typename std::aligned_union_t<Len, Types...> Type; };
|
template <size_t Len, typename... Types> struct TAlignedUnion { typedef typename std::aligned_union_t<Len, Types...> Type; };
|
||||||
template <typename T> struct TDecay { typedef typename std::decay_t<T> Type; };
|
template <typename T> struct TDecay { typedef typename std::decay_t<T> Type; };
|
||||||
template <typename T> struct TRemoveCVRef { typedef typename std::remove_cvref_t<T> Type; };
|
template <typename T> struct TRemoveCVRef { typedef typename std::remove_cvref_t<T> Type; };
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "HAL/Memory.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
NS_STD_USING
|
NS_STD_USING
|
||||||
NS_REDCRAFT_USING
|
NS_REDCRAFT_USING
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
int32* Ptr = new int32;
|
||||||
|
*Ptr = 13;
|
||||||
|
cout << *Ptr << endl;
|
||||||
|
delete Ptr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user