实现基本内存操作 Linux 平台测试
This commit is contained in:
parent
7361a673e4
commit
f53211ef50
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,5 +2,4 @@
|
||||
.vs/
|
||||
|
||||
# CMake generated files
|
||||
Build/
|
||||
Install/
|
||||
out/
|
||||
|
@ -4,12 +4,33 @@
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\Build\\${name}",
|
||||
"installRoot": "${projectDir}\\Install\\${name}",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"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 <new>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
@ -46,20 +47,36 @@ NS_REDCRAFT_BEGIN
|
||||
|
||||
// Alignment.
|
||||
|
||||
#if defined(__clang__)
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
#define GCC_PACK(n) __attribute__((packed,aligned(n)))
|
||||
#define GCC_ALIGN(n) __attribute__((aligned(n)))
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define MS_ALIGN(n) __declspec(align(n))
|
||||
#if defined(__clang__)
|
||||
|
||||
#define GCC_PACK(n) __attribute__((packed,aligned(n)))
|
||||
#define GCC_ALIGN(n) __attribute__((aligned(n)))
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define MS_ALIGN(n) __declspec(align(n))
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define GCC_PACK(n)
|
||||
#define GCC_ALIGN(n)
|
||||
#define MS_ALIGN(n) __declspec(align(n))
|
||||
|
||||
#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) __declspec(align(n))
|
||||
#define MS_ALIGN(n)
|
||||
|
||||
#endif
|
||||
|
||||
@ -114,10 +131,6 @@ typedef intptr_t ssize_t;
|
||||
typedef decltype(NULL) null_t;
|
||||
typedef std::nullptr_t nullptr_t;
|
||||
|
||||
// Alignment.
|
||||
|
||||
typedef std::max_align_t max_align_t;
|
||||
|
||||
#if PLATFORM_LINUX
|
||||
#define PLATFORM_TCHAR_IS_CHAR16 1
|
||||
#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_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_END NS_END(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 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 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 Result, typename Func, typename... ArgTypes> struct TIsInvocableResult { static constexpr bool Value = std::is_invocable_r_v<Result, Func, ArgTypes...>; };
|
||||
|
||||
@ -120,14 +119,14 @@ template <typename T> struct TRemoveAllExtents { typedef typename std::remove_al
|
||||
|
||||
// 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, 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 TRemoveCVRef { typedef typename std::remove_cvref_t<T> Type; };
|
||||
template <bool B, typename T, typename F> struct TConditional { typedef typename std::conditional_t<B, T, F> Type; };
|
||||
template <typename... T> struct TCommonType { typedef typename std::common_type_t<T...> Type; };
|
||||
template <typename T> struct TUnderlyingType { typedef typename std::underlying_type_t<T> Type; };
|
||||
template <typename Func, typename... ArgTypes> struct TInvokeResult { typedef typename std::invoke_result_t<Func, ArgTypes...> 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 <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 <bool B, typename T, typename F> struct TConditional { typedef typename std::conditional_t<B, T, F> Type; };
|
||||
template <typename... T> struct TCommonType { typedef typename std::common_type_t<T...> Type; };
|
||||
template <typename T> struct TUnderlyingType { typedef typename std::underlying_type_t<T> Type; };
|
||||
template <typename Func, typename... ArgTypes> struct TInvokeResult { typedef typename std::invoke_result_t<Func, ArgTypes...> Type; };
|
||||
|
||||
// Operations on traits
|
||||
|
||||
|
@ -1,12 +1,18 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "HAL/Memory.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
NS_STD_USING
|
||||
NS_REDCRAFT_USING
|
||||
|
||||
int main()
|
||||
{
|
||||
int32* Ptr = new int32;
|
||||
*Ptr = 13;
|
||||
cout << *Ptr << endl;
|
||||
delete Ptr;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user