diff options
| author | Stefan Boberg <[email protected]> | 2023-06-30 11:07:10 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2023-06-30 11:07:10 +0200 |
| commit | 0396f400a97f71bf743d584acc71a0cdbc155566 (patch) | |
| tree | 829f7764157aecf9c198e4b076e5fb1adcfeb13f /src | |
| parent | various zenhttp fixes from sb/proto (diff) | |
| download | zen-0396f400a97f71bf743d584acc71a0cdbc155566.tar.xz zen-0396f400a97f71bf743d584acc71a0cdbc155566.zip | |
* Added Guid::FromString
* Added LoadCompactBinaryObject from file to compactbinaryfile.cpp/h
* Added SaveCompactBinary(BinaryWriter& Ar, ...) functions
* Added ZEN_PLATFORM_NAME define
* Added SystemMetrics functionality to query system properties (see zencore/system.h)
Diffstat (limited to 'src')
| -rw-r--r-- | src/zencore/compactbinary.cpp | 48 | ||||
| -rw-r--r-- | src/zencore/compactbinaryfile.cpp | 33 | ||||
| -rw-r--r-- | src/zencore/filesystem.cpp | 69 | ||||
| -rw-r--r-- | src/zencore/include/zencore/compactbinary.h | 14 | ||||
| -rw-r--r-- | src/zencore/include/zencore/compactbinarybuilder.h | 4 | ||||
| -rw-r--r-- | src/zencore/include/zencore/compactbinaryfile.h | 18 | ||||
| -rw-r--r-- | src/zencore/include/zencore/filesystem.h | 10 | ||||
| -rw-r--r-- | src/zencore/include/zencore/fmtutils.h | 19 | ||||
| -rw-r--r-- | src/zencore/include/zencore/guid.h | 26 | ||||
| -rw-r--r-- | src/zencore/include/zencore/iobuffer.h | 1 | ||||
| -rw-r--r-- | src/zencore/include/zencore/iohash.h | 3 | ||||
| -rw-r--r-- | src/zencore/include/zencore/string.h | 11 | ||||
| -rw-r--r-- | src/zencore/include/zencore/system.h | 37 | ||||
| -rw-r--r-- | src/zencore/include/zencore/thread.h | 5 | ||||
| -rw-r--r-- | src/zencore/include/zencore/uid.h | 2 | ||||
| -rw-r--r-- | src/zencore/include/zencore/zencore.h | 9 | ||||
| -rw-r--r-- | src/zencore/session.cpp | 4 | ||||
| -rw-r--r-- | src/zencore/system.cpp | 199 | ||||
| -rw-r--r-- | src/zencore/testing.cpp | 10 | ||||
| -rw-r--r-- | src/zencore/thread.cpp | 2 | ||||
| -rw-r--r-- | src/zencore/uid.cpp | 3 | ||||
| -rw-r--r-- | src/zencore/xmake.lua | 1 |
22 files changed, 490 insertions, 38 deletions
diff --git a/src/zencore/compactbinary.cpp b/src/zencore/compactbinary.cpp index 0db9f02ea..5b599dda3 100644 --- a/src/zencore/compactbinary.cpp +++ b/src/zencore/compactbinary.cpp @@ -358,6 +358,34 @@ Guid::ToString(StringBuilderBase& Sb) const return Sb; } +Guid +Guid::FromString(std::string_view InString) +{ + if (InString.size() != 36) + { + } + + bool Ok = true; + + uint32_t V0 = 0, V5 = 0; + uint16_t V1 = 0, V2 = 0, V3 = 0, V4 = 0; + + Ok = Ok && ParseHexNumber(InString.substr(0, 8), /* out */ V0); + Ok = Ok && ParseHexNumber(InString.substr(9, 4), /* out */ V1); + Ok = Ok && ParseHexNumber(InString.substr(14, 4), /* out */ V2); + Ok = Ok && ParseHexNumber(InString.substr(19, 4), /* out */ V3); + Ok = Ok && ParseHexNumber(InString.substr(24, 4), /* out */ V4); + Ok = Ok && ParseHexNumber(InString.substr(28, 8), /* out */ V5); + + Guid Value; + Value.A = V0; + Value.B = V1 << 16 | V2; + Value.C = V3 << 16 | V4; + Value.D = V5; + + return Value; +} + ////////////////////////////////////////////////////////////////////////// namespace CompactBinaryPrivate { @@ -1943,6 +1971,22 @@ uson_forcelink() { } +TEST_CASE("guid") +{ + using namespace std::literals; + + const Guid A = Guid::FromString("03000c43-d267-36fd-9164-a7555824822b"sv); + + StringBuilder<40> GuidStr; + A.ToString(GuidStr); + + CHECK(std::string_view(GuidStr) == "03000c43-d267-36fd-9164-a7555824822b"sv); + + const Guid B = Guid::FromString(GuidStr); + + CHECK(A == B); +} + TEST_CASE("uson") { using namespace std::literals; @@ -2142,8 +2186,8 @@ TEST_CASE("uson.json") SUBCASE("number.nan") { - const float FloatNan = std::numeric_limits<float>::quiet_NaN(); - const double DoubleNan = std::numeric_limits<double>::quiet_NaN(); + constexpr float FloatNan = std::numeric_limits<float>::quiet_NaN(); + constexpr double DoubleNan = std::numeric_limits<double>::quiet_NaN(); CbObjectWriter Writer; Writer << "FloatNan" << FloatNan; diff --git a/src/zencore/compactbinaryfile.cpp b/src/zencore/compactbinaryfile.cpp new file mode 100644 index 000000000..f2121a0bd --- /dev/null +++ b/src/zencore/compactbinaryfile.cpp @@ -0,0 +1,33 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "zencore/compactbinaryfile.h" +#include "zencore/compactbinaryvalidation.h" + +#include <zencore/filesystem.h> + +namespace zen { + +CbObjectFromFile +LoadCompactBinaryObject(const std::filesystem::path& FilePath) +{ + FileContents ObjectFile = ReadFile(FilePath); + + if (ObjectFile.ErrorCode) + { + throw std::system_error(ObjectFile.ErrorCode); + } + + IoBuffer ObjectBuffer = ObjectFile.Flatten(); + + if (CbValidateError Result = ValidateCompactBinary(ObjectBuffer, CbValidateMode::All); Result == CbValidateError::None) + { + CbObject Object = LoadCompactBinaryObject(ObjectBuffer); + const IoHash WorkerId = IoHash::HashBuffer(ObjectBuffer); + + return {.Object = Object, .Hash = WorkerId}; + } + + return {.Hash = IoHash::Zero}; +} + +} // namespace zen diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index cde4c52ab..059d1b5f0 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -2,6 +2,7 @@ #include <zencore/filesystem.h> +#include <zencore/compositebuffer.h> #include <zencore/except.h> #include <zencore/fmtutils.h> #include <zencore/iobuffer.h> @@ -100,6 +101,8 @@ WipeDirectory(const wchar_t* DirPath) WIN32_FIND_DATAW FindData; HANDLE hFind = FindFirstFileW(Pattern.c_str(), &FindData); + bool Success = true; + if (hFind != nullptr) { do @@ -135,27 +138,43 @@ WipeDirectory(const wchar_t* DirPath) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_RECALL_ON_OPEN) { - DeleteReparsePoint(Path.c_str(), FindData.dwReserved0); + if (!DeleteReparsePoint(Path.c_str(), FindData.dwReserved0)) + { + Success = false; + } } if (FindData.dwFileAttributes & FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS) { - DeleteReparsePoint(Path.c_str(), FindData.dwReserved0); + if (!DeleteReparsePoint(Path.c_str(), FindData.dwReserved0)) + { + Success = false; + } } - bool Success = DeleteDirectories(Path.c_str()); + bool Succeeded = DeleteDirectories(Path.c_str()); - if (!Success) + if (!Succeeded) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - DeleteReparsePoint(Path.c_str(), FindData.dwReserved0); + if (!DeleteReparsePoint(Path.c_str(), FindData.dwReserved0)) + { + Success = false; + } } } } else { - DeleteFileW(Path.c_str()); + BOOL Succeeded = DeleteFileW(Path.c_str()); + + if (!Succeeded) + { + // We should emit a warning here, but this is quite low level so care + // needs to be taken. + Success = false; + } } } } while (FindNextFileW(hFind, &FindData) == TRUE); @@ -633,6 +652,26 @@ WriteFile(std::filesystem::path Path, IoBuffer Data) WriteFile(Path, &DataPtr, 1); } +void +WriteFile(std::filesystem::path Path, CompositeBuffer InData) +{ + std::vector<IoBuffer> DataVec; + + for (const SharedBuffer& Segment : InData.GetSegments()) + { + DataVec.push_back(Segment.AsIoBuffer()); + } + + std::vector<const IoBuffer*> DataPtrs; + + for (IoBuffer& Data : DataVec) + { + DataPtrs.push_back(&Data); + } + + WriteFile(Path, DataPtrs.data(), DataPtrs.size()); +} + IoBuffer FileContents::Flatten() { @@ -676,7 +715,13 @@ ReadFile(std::filesystem::path Path) void* Handle; #if ZEN_PLATFORM_WINDOWS - windows::Handle FromFile(CreateFileW(Path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr)); + windows::Handle FromFile(CreateFileW(Path.c_str(), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, + OPEN_EXISTING, + 0, + nullptr)); if (FromFile == INVALID_HANDLE_VALUE) { FromFile.Detach(); @@ -717,7 +762,13 @@ bool ScanFile(std::filesystem::path Path, const uint64_t ChunkSize, std::function<void(const void* Data, size_t Size)>&& ProcessFunc) { #if ZEN_PLATFORM_WINDOWS - windows::Handle FromFile(CreateFileW(Path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr)); + windows::Handle FromFile(CreateFileW(Path.c_str(), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, + OPEN_EXISTING, + 0, + nullptr)); if (FromFile == INVALID_HANDLE_VALUE) { FromFile.Detach(); @@ -1047,6 +1098,8 @@ std::filesystem::path GetRunningExecutablePath() { #if ZEN_PLATFORM_WINDOWS + // TODO: make this long path aware + TCHAR ExePath[MAX_PATH]; DWORD PathLength = GetModuleFileName(NULL, ExePath, ZEN_ARRAY_COUNT(ExePath)); diff --git a/src/zencore/include/zencore/compactbinary.h b/src/zencore/include/zencore/compactbinary.h index b546f97aa..66e621a8a 100644 --- a/src/zencore/include/zencore/compactbinary.h +++ b/src/zencore/include/zencore/compactbinary.h @@ -5,6 +5,7 @@ #include <zencore/zencore.h> #include <zencore/enumflags.h> +#include <zencore/guid.h> #include <zencore/intmath.h> #include <zencore/iobuffer.h> #include <zencore/iohash.h> @@ -141,13 +142,6 @@ private: uint64_t Ticks; }; -struct Guid -{ - uint32_t A, B, C, D; - - StringBuilderBase& ToString(StringBuilderBase& OutString) const; -}; - ////////////////////////////////////////////////////////////////////////// /** @@ -891,6 +885,8 @@ public: /** @see CbField::CbField */ using CbFieldView::CbFieldView; + using CbFieldView::TryGetSerializedView; + /** Construct an array with no fields. */ ZENCORE_API CbArrayView(); @@ -1410,6 +1406,10 @@ ZENCORE_API CbObject LoadCompactBinaryObject(const CompressedBuffer& Payload); ZENCORE_API CbFieldIterator LoadCompactBinaryFromJson(std::string_view Json, std::string& Error); ZENCORE_API CbFieldIterator LoadCompactBinaryFromJson(std::string_view Json); +ZENCORE_API void SaveCompactBinary(BinaryWriter& Ar, const CbFieldView& Field); +ZENCORE_API void SaveCompactBinary(BinaryWriter& Ar, const CbArrayView& Array); +ZENCORE_API void SaveCompactBinary(BinaryWriter& Ar, const CbObjectView& Object); + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** diff --git a/src/zencore/include/zencore/compactbinarybuilder.h b/src/zencore/include/zencore/compactbinarybuilder.h index 4be8c2ba5..53f00ae4e 100644 --- a/src/zencore/include/zencore/compactbinarybuilder.h +++ b/src/zencore/include/zencore/compactbinarybuilder.h @@ -46,7 +46,7 @@ class BinaryWriter; * * Example: * - * CbObjectRef WriteObject() + * CbObject WriteObject() * { * CbWriter<256> Writer; * Writer.BeginObject(); @@ -60,7 +60,7 @@ class BinaryWriter; * Writer.EndArray(); * * Writer.EndObject(); - * return Writer.Save().AsObjectRef(); + * return Writer.Save().AsObject(); * } */ class CbWriter diff --git a/src/zencore/include/zencore/compactbinaryfile.h b/src/zencore/include/zencore/compactbinaryfile.h new file mode 100644 index 000000000..00c37e941 --- /dev/null +++ b/src/zencore/include/zencore/compactbinaryfile.h @@ -0,0 +1,18 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <zencore/compactbinary.h> +#include <zencore/iohash.h> + +#include <filesystem> + +namespace zen { + +struct CbObjectFromFile +{ + CbObject Object; + IoHash Hash; +}; + +CbObjectFromFile LoadCompactBinaryObject(const std::filesystem::path& FilePath); + +} // namespace zen diff --git a/src/zencore/include/zencore/filesystem.h b/src/zencore/include/zencore/filesystem.h index 230d8d1c2..1a582672b 100644 --- a/src/zencore/include/zencore/filesystem.h +++ b/src/zencore/include/zencore/filesystem.h @@ -14,6 +14,7 @@ namespace zen { class IoBuffer; +class CompositeBuffer; /** Delete directory (after deleting any contents) */ @@ -52,10 +53,19 @@ struct FileContents }; ZENCORE_API FileContents ReadStdIn(); + +/** Prepare file for reading + + Note that this generally does not actually read the file contents. Instead it creates an + IoBuffer referencing the file contents so that it may be read at a later time. This is + leveraged to allow sending of data straight from disk cache and other optimizations. + */ ZENCORE_API FileContents ReadFile(std::filesystem::path Path); + ZENCORE_API bool ScanFile(std::filesystem::path Path, uint64_t ChunkSize, std::function<void(const void* Data, size_t Size)>&& ProcessFunc); ZENCORE_API void WriteFile(std::filesystem::path Path, const IoBuffer* const* Data, size_t BufferCount); ZENCORE_API void WriteFile(std::filesystem::path Path, IoBuffer Data); +ZENCORE_API void WriteFile(std::filesystem::path Path, CompositeBuffer Data); struct CopyFileOptions { diff --git a/src/zencore/include/zencore/fmtutils.h b/src/zencore/include/zencore/fmtutils.h index 70867fe72..5c5169cd6 100644 --- a/src/zencore/include/zencore/fmtutils.h +++ b/src/zencore/include/zencore/fmtutils.h @@ -2,6 +2,7 @@ #pragma once +#include <zencore/guid.h> #include <zencore/iohash.h> #include <zencore/string.h> #include <zencore/uid.h> @@ -23,7 +24,7 @@ struct fmt::formatter<zen::IoHash> : formatter<string_view> { zen::IoHash::String_t String; Hash.ToHexString(String); - return formatter<string_view>::format({String, zen::IoHash::StringLength}, ctx); + return fmt::formatter<string_view>::format({String, zen::IoHash::StringLength}, ctx); } }; @@ -35,7 +36,19 @@ struct fmt::formatter<zen::Oid> : formatter<string_view> { zen::StringBuilder<32> String; Id.ToString(String); - return formatter<string_view>::format({String.c_str(), zen::Oid::StringLength}, ctx); + return fmt::formatter<string_view>::format({String.c_str(), zen::Oid::StringLength}, ctx); + } +}; + +template<> +struct fmt::formatter<zen::Guid> : formatter<string_view> +{ + template<typename FormatContext> + auto format(const zen::Guid& Id, FormatContext& ctx) + { + zen::StringBuilder<48> String; + Id.ToString(String); + return fmt::formatter<string_view>::format({String.c_str(), zen::Guid::StringLength}, ctx); } }; @@ -47,6 +60,6 @@ struct fmt::formatter<std::filesystem::path> : formatter<string_view> { zen::ExtendableStringBuilder<128> String; String << Path.u8string(); - return formatter<string_view>::format(String.ToView(), ctx); + return fmt::formatter<string_view>::format(String.ToView(), ctx); } }; diff --git a/src/zencore/include/zencore/guid.h b/src/zencore/include/zencore/guid.h new file mode 100644 index 000000000..751aa945f --- /dev/null +++ b/src/zencore/include/zencore/guid.h @@ -0,0 +1,26 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/zencore.h> +#include <compare> + +namespace zen { + +class StringBuilderBase; + +struct Guid +{ + uint32_t A, B, C, D; + + static const int StringLength = 36; + typedef char String_t[StringLength + 1]; + + StringBuilderBase& ToString(StringBuilderBase& OutString) const; + static Guid FromString(std::string_view InString); + + inline bool operator==(const Guid& Rhs) const = default; + inline auto operator<=>(const Guid& Rhs) const = default; +}; + +} // namespace zen diff --git a/src/zencore/include/zencore/iobuffer.h b/src/zencore/include/zencore/iobuffer.h index 2f248eb8b..bbc346f9b 100644 --- a/src/zencore/include/zencore/iobuffer.h +++ b/src/zencore/include/zencore/iobuffer.h @@ -414,6 +414,7 @@ public: /** Make sure buffer data is memory resident, but avoid memory mapping data from files */ ZENCORE_API static IoBuffer ReadFromFileMaybe(IoBuffer& InBuffer); + inline static IoBuffer MakeFromMemory(MemoryView Memory) { return IoBuffer(IoBuffer::Wrap, Memory.GetData(), Memory.GetSize()); } inline static IoBuffer MakeCloneFromMemory(const void* Ptr, size_t Sz) { if (Sz) diff --git a/src/zencore/include/zencore/iohash.h b/src/zencore/include/zencore/iohash.h index fd0f4b2a7..649a59c2c 100644 --- a/src/zencore/include/zencore/iohash.h +++ b/src/zencore/include/zencore/iohash.h @@ -42,6 +42,9 @@ struct IoHash return Io; } + // Temporary helper for transitioning APIs + static IoHash FromBLAKE3(const IoHash& Hash) { return Hash; } + static IoHash HashBuffer(const void* data, size_t byteCount); static IoHash HashBuffer(MemoryView Data) { return HashBuffer(Data.GetData(), Data.GetSize()); } static IoHash HashBuffer(const CompositeBuffer& Buffer); diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h index ab111ff81..7a44bf781 100644 --- a/src/zencore/include/zencore/string.h +++ b/src/zencore/include/zencore/string.h @@ -306,6 +306,8 @@ public: inline StringBuilderImpl& operator<<(const std::string_view str) { return AppendAscii(str); } inline StringBuilderImpl& operator<<(const std::u8string_view str) { return AppendAscii(str); } + inline void EnsureNulTerminated() const { *m_CurPos = '\0'; } + protected: inline void Init(C* Base, size_t Capacity) { @@ -313,8 +315,6 @@ protected: m_End = Base + Capacity; } - inline void EnsureNulTerminated() const { *m_CurPos = '\0'; } - inline void EnsureCapacity(size_t ExtraRequired) { // precondition: we know the current buffer has enough capacity @@ -607,14 +607,13 @@ ToHexNumber(UnsignedIntegral auto Value, char* OutString) /// <summary> /// Parse hex number string into a value, this formats the number in the correct order for a hexadecimal number /// </summary> -/// <param name="string">Input string</param> -/// <param name="characterCount">Number of characters in string</param> +/// <param name="HexString">Input string</param> /// <param name="OutValue">Pointer to output value</param> /// <returns>true if the input consisted of all valid hexadecimal characters</returns> bool -ParseHexNumber(const std::string HexString, UnsignedIntegral auto& OutValue) +ParseHexNumber(const std::string_view HexString, UnsignedIntegral auto& OutValue) { - return ParseHexNumber(HexString.c_str(), sizeof(OutValue) * 2, (uint8_t*)&OutValue); + return ParseHexNumber(HexString.data(), sizeof(OutValue) * 2, (uint8_t*)&OutValue); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/zencore/include/zencore/system.h b/src/zencore/include/zencore/system.h new file mode 100644 index 000000000..23665fb09 --- /dev/null +++ b/src/zencore/include/zencore/system.h @@ -0,0 +1,37 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/zencore.h> + +#include <string> + +namespace zen { + +class CbWriter; + +std::string GetMachineName(); +std::string_view GetOperatingSystemName(); +std::string_view GetCpuName(); + +struct SystemMetrics +{ + int CpuCount = 1; + int CoreCount = 1; + int LogicalProcessorCount = 1; + uint64_t SystemMemoryMiB = 0; + uint64_t AvailSystemMemoryMiB = 0; + uint64_t VirtualMemoryMiB = 0; + uint64_t AvailVirtualMemoryMiB = 0; + uint64_t PageFileMiB = 0; + uint64_t AvailPageFileMiB = 0; +}; + +SystemMetrics GetSystemMetrics(); + +void SetCpuCountForReporting(int FakeCpuCount); +SystemMetrics GetSystemMetricsForReporting(); + +void Describe(const SystemMetrics& Metrics, CbWriter& Writer); + +} // namespace zen diff --git a/src/zencore/include/zencore/thread.h b/src/zencore/include/zencore/thread.h index 9ff98de8c..9f2671610 100644 --- a/src/zencore/include/zencore/thread.h +++ b/src/zencore/include/zencore/thread.h @@ -107,6 +107,10 @@ public: ZENCORE_API bool Wait(int TimeoutMs = -1); ZENCORE_API void Close(); +#if ZEN_PLATFORM_WINDOWS + inline void* GetWindowsHandle() { return m_EventHandle; } +#endif + protected: explicit Event(void* EventHandle) : m_EventHandle(EventHandle) {} @@ -181,6 +185,7 @@ public: void AddCount(std::ptrdiff_t Count) { std::atomic_ptrdiff_t Old = Counter.fetch_add(Count); + ZEN_UNUSED(Old); ZEN_ASSERT_SLOW(Old > 0); } diff --git a/src/zencore/include/zencore/uid.h b/src/zencore/include/zencore/uid.h index a356da88d..4a1285416 100644 --- a/src/zencore/include/zencore/uid.h +++ b/src/zencore/include/zencore/uid.h @@ -60,7 +60,7 @@ struct Oid const Oid& Generate(); [[nodiscard]] static Oid FromHexString(const std::string_view String); StringBuilderBase& ToString(StringBuilderBase& OutString) const; - void ToString(char OutString[StringLength]); + void ToString(char OutString[StringLength]) const; [[nodiscard]] static Oid FromMemory(const void* Ptr); auto operator<=>(const Oid& rhs) const = default; diff --git a/src/zencore/include/zencore/zencore.h b/src/zencore/include/zencore/zencore.h index 47ff2ebc2..71bd08e69 100644 --- a/src/zencore/include/zencore/zencore.h +++ b/src/zencore/include/zencore/zencore.h @@ -22,12 +22,15 @@ #ifdef _WIN32 # undef ZEN_PLATFORM_WINDOWS # define ZEN_PLATFORM_WINDOWS 1 +# define ZEN_PLATFORM_NAME "Windows" #elif defined(__linux__) # undef ZEN_PLATFORM_LINUX # define ZEN_PLATFORM_LINUX 1 +# define ZEN_PLATFORM_NAME "Linux" #elif defined(__APPLE__) # undef ZEN_PLATFORM_MAC -# define ZEN_PLATFORM_MAC 1 +# define ZEN_PLATFORM_MAC 1 +# define ZEN_PLATFORM_NAME "MacOS" #endif #if ZEN_PLATFORM_WINDOWS @@ -201,9 +204,11 @@ concept ContiguousRange = true; #ifdef NDEBUG # define ZEN_BUILD_DEBUG 0 # define ZEN_BUILD_RELEASE 1 +# define ZEN_BUILD_NAME "release" #else # define ZEN_BUILD_DEBUG 1 # define ZEN_BUILD_RELEASE 0 +# define ZEN_BUILD_NAME "debug" #endif ////////////////////////////////////////////////////////////////////////// @@ -323,7 +328,7 @@ char (&ZenArrayCountHelper(const T (&)[N]))[N + 1]; #if ZEN_PLATFORM_WINDOWS # define ZEN_EXE_SUFFIX_LITERAL ".exe" #else -# define ZEN_EXE_SUFFIX_LITERAL +# define ZEN_EXE_SUFFIX_LITERAL "" #endif #define ZEN_UNUSED(...) ((void)__VA_ARGS__) diff --git a/src/zencore/session.cpp b/src/zencore/session.cpp index ce4bfae1b..50c47c628 100644 --- a/src/zencore/session.cpp +++ b/src/zencore/session.cpp @@ -9,7 +9,7 @@ namespace zen { static Oid GlobalSessionId; -static char GlobalSessionString[Oid::StringLength]; +static Oid::String_t GlobalSessionString; static std::once_flag SessionInitFlag; Oid @@ -32,4 +32,4 @@ GetSessionIdString() return std::string_view(GlobalSessionString, Oid::StringLength); } -} // namespace zen
\ No newline at end of file +} // namespace zen diff --git a/src/zencore/system.cpp b/src/zencore/system.cpp new file mode 100644 index 000000000..f51273e0d --- /dev/null +++ b/src/zencore/system.cpp @@ -0,0 +1,199 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "zencore/system.h" + +#include <zencore/compactbinarybuilder.h> +#include <zencore/except.h> +#include <zencore/string.h> + +#if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> + +ZEN_THIRD_PARTY_INCLUDES_START +# include <iphlpapi.h> +# include <winsock2.h> +ZEN_THIRD_PARTY_INCLUDES_END +#elif ZEN_PLATFORM_LINUX +# include <sys/utsname.h> +#elif ZEN_PLATFORM_MAC +# include <unistd.h> +#endif + +namespace zen { + +using namespace std::literals; + +int g_FakeCpuCount = 0; + +void +SetCpuCountForReporting(int FakeCpuCount) +{ + g_FakeCpuCount = FakeCpuCount; +} + +#if ZEN_PLATFORM_WINDOWS +std::string +GetMachineName() +{ + WCHAR NameBuffer[256]; + DWORD dwNameSize = 255; + BOOL Success = GetComputerNameW(NameBuffer, &dwNameSize); + + if (Success) + { + return WideToUtf8(NameBuffer); + } + + return {}; +} + +SystemMetrics +GetSystemMetrics() +{ + SYSTEM_INFO SysInfo{}; + GetSystemInfo(&SysInfo); + + SystemMetrics Metrics; + + Metrics.LogicalProcessorCount = SysInfo.dwNumberOfProcessors; + + // Determine physical core count + + DWORD BufferSize = 0; + BOOL Result = GetLogicalProcessorInformation(nullptr, &BufferSize); + if (int32_t Error = GetLastError(); Error != ERROR_INSUFFICIENT_BUFFER) + { + ThrowSystemError(Error, "Failed to get buffer size for logical processor information"); + } + + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)Memory::Alloc(BufferSize); + + Result = GetLogicalProcessorInformation(Buffer, &BufferSize); + if (!Result) + { + Memory::Free(Buffer); + throw std::runtime_error("Failed to get logical processor information"); + } + + DWORD ProcessorPkgCount = 0; + DWORD ProcessorCoreCount = 0; + DWORD ByteOffset = 0; + while (ByteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= BufferSize) + { + const SYSTEM_LOGICAL_PROCESSOR_INFORMATION& Slpi = Buffer[ByteOffset / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]; + if (Slpi.Relationship == RelationProcessorCore) + { + ProcessorCoreCount++; + } + else if (Slpi.Relationship == RelationProcessorPackage) + { + ProcessorPkgCount++; + } + ByteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); + } + + Metrics.CoreCount = ProcessorCoreCount; + Metrics.CpuCount = ProcessorPkgCount; + + Memory::Free(Buffer); + + // Query memory status + + MEMORYSTATUSEX MemStatus{.dwLength = sizeof(MEMORYSTATUSEX)}; + GlobalMemoryStatusEx(&MemStatus); + + Metrics.SystemMemoryMiB = MemStatus.ullTotalPhys / 1024 / 1024; + Metrics.AvailSystemMemoryMiB = MemStatus.ullAvailPhys / 1024 / 1024; + Metrics.VirtualMemoryMiB = MemStatus.ullTotalVirtual / 1024 / 1024; + Metrics.AvailVirtualMemoryMiB = MemStatus.ullAvailVirtual / 1024 / 1024; + Metrics.PageFileMiB = MemStatus.ullTotalPageFile / 1024 / 1024; + Metrics.AvailPageFileMiB = MemStatus.ullAvailPageFile / 1024 / 1024; + + return Metrics; +} +#elif ZEN_PLATFORM_LINUX +std::string +GetMachineName() +{ + static char Result[256] = ""; + if (!Result[0]) + { + struct utsname name; + const char* SysName = name.nodename; + if (uname(&name)) + { + SysName = "Unix Computer"; + } + + strcpy(Result, SysName); + } + return Result; +} + +SystemMetrics +GetSystemMetrics() +{ + return {}; +} +#elif ZEN_PLATFORM_MAC +std::string +GetMachineName() +{ + static char Result[256] = ""; + + if (!Result[0]) + { + gethostname(Result, sizeof(Result)); + } + return Result; +} + +SystemMetrics +GetSystemMetrics() +{ + return {}; +} +#else +# error "Unknown platform" +#endif + +SystemMetrics +GetSystemMetricsForReporting() +{ + SystemMetrics Sm = GetSystemMetrics(); + + if (g_FakeCpuCount) + { + Sm.CoreCount = g_FakeCpuCount; + Sm.LogicalProcessorCount = g_FakeCpuCount; + } + + return Sm; +} + +std::string_view +GetOperatingSystemName() +{ + return ZEN_PLATFORM_NAME; +} + +std::string_view +GetCpuName() +{ +#if ZEN_ARCH_X64 + return "x64"sv; +#elif ZEN_ARCH_ARM64 + return "arm64"sv; +#endif +} + +void +Describe(const SystemMetrics& Metrics, CbWriter& Writer) +{ + Writer << "cpu_count" << Metrics.CpuCount << "core_count" << Metrics.CoreCount << "lp_count" << Metrics.LogicalProcessorCount + << "total_memory_mb" << Metrics.SystemMemoryMiB << "avail_memory_mb" << Metrics.AvailSystemMemoryMiB << "total_virtual_mb" + << Metrics.VirtualMemoryMiB << "avail_virtual_mb" << Metrics.AvailVirtualMemoryMiB << "total_pagefile_mb" << Metrics.PageFileMiB + << "avail_pagefile_mb" << Metrics.AvailPageFileMiB; +} + +} // namespace zen diff --git a/src/zencore/testing.cpp b/src/zencore/testing.cpp index 5531aa738..6e1f55eda 100644 --- a/src/zencore/testing.cpp +++ b/src/zencore/testing.cpp @@ -34,6 +34,10 @@ TestRunner::ApplyCommandLine(int argc, char const* const* argv) { spdlog::set_level(spdlog::level::debug); } + else if (argv[i] == "--verbose"sv) + { + spdlog::set_level(spdlog::level::trace); + } } return 0; @@ -42,11 +46,9 @@ TestRunner::ApplyCommandLine(int argc, char const* const* argv) int TestRunner::Run() { - int Rv = m_Impl->Session.run(); - - return Rv; + return m_Impl->Session.run(); } } // namespace zen::testing -#endif +#endif // ZEN_WITH_TESTS diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp index a44c0ee90..b225c8aff 100644 --- a/src/zencore/thread.cpp +++ b/src/zencore/thread.cpp @@ -18,6 +18,8 @@ # include <shellapi.h> # include <Shlobj.h> # include <zencore/windows.h> +# pragma comment(lib, "shell32.lib") +# pragma comment(lib, "user32.lib") #else # include <chrono> # include <condition_variable> diff --git a/src/zencore/uid.cpp b/src/zencore/uid.cpp index 86cdfae3a..0f04d70ac 100644 --- a/src/zencore/uid.cpp +++ b/src/zencore/uid.cpp @@ -91,9 +91,10 @@ Oid::FromMemory(const void* Ptr) } void -Oid::ToString(char OutString[StringLength]) +Oid::ToString(char OutString[StringLength]) const { ToHexBytes(reinterpret_cast<const uint8_t*>(OidBits), sizeof(Oid::OidBits), OutString); + OutString[StringLength] = '\0'; } StringBuilderBase& diff --git a/src/zencore/xmake.lua b/src/zencore/xmake.lua index ef68b4c3c..706adff81 100644 --- a/src/zencore/xmake.lua +++ b/src/zencore/xmake.lua @@ -2,6 +2,7 @@ target('zencore') set_kind("static") + set_group("libs") add_headerfiles("**.h") add_configfiles("include/zencore/config.h.in") on_load(function (target) |