实现基本内存操作 Linux 平台测试

This commit is contained in:
_Redstone_c_ 2021-10-05 18:33:18 +08:00
parent 7361a673e4
commit f53211ef50
11 changed files with 330 additions and 26 deletions

3
.gitignore vendored
View File

@ -2,5 +2,4 @@
.vs/
# CMake generated files
Build/
Install/
out/

View File

@ -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": []
}
]
}

View 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

View 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); }

View 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

View File

@ -2,6 +2,7 @@
#include "Misc/CoreDefines.h"
#include <new>
#include <cstdint>
#include <cstdlib>
#include <cstddef>
@ -46,6 +47,8 @@ NS_REDCRAFT_BEGIN
// Alignment.
#if PLATFORM_WINDOWS
#if defined(__clang__)
#define GCC_PACK(n) __attribute__((packed,aligned(n)))
@ -63,6 +66,20 @@ NS_REDCRAFT_BEGIN
#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.
#if PLATFORM_WINDOWS
@ -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

View 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

View File

@ -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)

View 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

View File

@ -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,7 +119,7 @@ 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, 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; };

View File

@ -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;
}