diff options
29 files changed, 387 insertions, 43 deletions
diff --git a/3rdparty/BLAKE3/lib/Linux_x64/libblake3.a b/3rdparty/BLAKE3/lib/Linux_x64/libblake3.a Binary files differnew file mode 100644 index 000000000..b956e22cb --- /dev/null +++ b/3rdparty/BLAKE3/lib/Linux_x64/libblake3.a diff --git a/3rdparty/Oodle/lib/Linux_x64/liboo2corelinux64.a b/3rdparty/Oodle/lib/Linux_x64/liboo2corelinux64.a Binary files differnew file mode 100755 index 000000000..dee0353e5 --- /dev/null +++ b/3rdparty/Oodle/lib/Linux_x64/liboo2corelinux64.a diff --git a/3rdparty/Oodle/lib/Linux_x64/liboo2corelinux64.so.8 b/3rdparty/Oodle/lib/Linux_x64/liboo2corelinux64.so.8 Binary files differnew file mode 100755 index 000000000..425ada44d --- /dev/null +++ b/3rdparty/Oodle/lib/Linux_x64/liboo2corelinux64.so.8 @@ -35,6 +35,10 @@ if is_mode("debug") then add_defines("DEBUG") end +if is_os("windows") then + add_defines("_CRT_SECURE_NO_WARNINGS") +end + add_defines("USE_SENTRY=1") option("vfs") diff --git a/zencore/compress.cpp b/zencore/compress.cpp index 2b2c4dd0b..55808375e 100644 --- a/zencore/compress.cpp +++ b/zencore/compress.cpp @@ -8,11 +8,14 @@ #include <zencore/endian.h> #include "../3rdparty/Oodle/include/oodle2.h" -#pragma comment(lib, "oo2core_win64.lib") +#if ZEN_PLATFORM_WINDOWS +# pragma comment(lib, "oo2core_win64.lib") +#endif #include <doctest/doctest.h> #include <lz4.h> #include <functional> +#include <limits> namespace zen::detail { diff --git a/zencore/include/zencore/atomic.h b/zencore/include/zencore/atomic.h index 457128bd4..7e261771b 100644 --- a/zencore/include/zencore/atomic.h +++ b/zencore/include/zencore/atomic.h @@ -2,7 +2,14 @@ #pragma once +#include <zencore/zencore.h> + +#if ZEN_COMPILER_MSC #include <intrin.h> +#else +#include <atomic> +#endif + #include <cinttypes> namespace zen { @@ -10,34 +17,58 @@ namespace zen { inline uint32_t AtomicIncrement(volatile uint32_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedIncrement((long volatile*)&value); +#else + return ((std::atomic<uint32_t>*)(&value))->fetch_add(1, std::memory_order_seq_cst) + 1; +#endif } inline uint32_t AtomicDecrement(volatile uint32_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedDecrement((long volatile*)&value); +#else + return ((std::atomic<uint32_t>*)(&value))->fetch_sub(1, std::memory_order_seq_cst) - 1; +#endif } inline uint64_t AtomicIncrement(volatile uint64_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedIncrement64((__int64 volatile*)&value); +#else + return ((std::atomic<uint64_t>*)(&value))->fetch_add(1, std::memory_order_seq_cst) + 1; +#endif } inline uint64_t AtomicDecrement(volatile uint64_t& value) { +#if ZEN_COMPILER_MSC return _InterlockedDecrement64((__int64 volatile*)&value); +#else + return ((std::atomic<uint64_t>*)(&value))->fetch_sub(1, std::memory_order_seq_cst) - 1; +#endif } inline uint32_t AtomicAdd(volatile uint32_t& value, uint32_t amount) { +#if ZEN_COMPILER_MSC return _InterlockedExchangeAdd((long volatile*)&value, amount); +#else + return ((std::atomic<uint32_t>*)(&value))->fetch_add(amount, std::memory_order_seq_cst); +#endif } inline uint64_t AtomicAdd(volatile uint64_t& value, uint64_t amount) { +#if ZEN_COMPILER_MSC return _InterlockedExchangeAdd64((__int64 volatile*)&value, amount); +#else + return ((std::atomic<uint64_t>*)(&value))->fetch_add(amount, std::memory_order_seq_cst); +#endif } } // namespace zen diff --git a/zencore/include/zencore/compactbinary.h b/zencore/include/zencore/compactbinary.h index 09619be8b..4fce129ea 100644 --- a/zencore/include/zencore/compactbinary.h +++ b/zencore/include/zencore/compactbinary.h @@ -748,6 +748,8 @@ private: friend class CbFieldViewIterator; + friend class CbFieldIterator; + /** Pointer to the first byte past the end of the last field. Set to null at the end. */ const void* FieldsEnd = nullptr; }; diff --git a/zencore/include/zencore/compactbinarybuilder.h b/zencore/include/zencore/compactbinarybuilder.h index f7f2bbfd3..5f6d9fd0c 100644 --- a/zencore/include/zencore/compactbinarybuilder.h +++ b/zencore/include/zencore/compactbinarybuilder.h @@ -533,7 +533,7 @@ operator<<(CbWriter& Writer, const CbArray& Value) } inline CbWriter& -operator<<(CbWriter& Writer, nullptr_t) +operator<<(CbWriter& Writer, std::nullptr_t) { Writer.AddNull(); return Writer; diff --git a/zencore/include/zencore/endian.h b/zencore/include/zencore/endian.h index 1f79a59e8..d44a27b01 100644 --- a/zencore/include/zencore/endian.h +++ b/zencore/include/zencore/endian.h @@ -7,19 +7,31 @@ namespace zen { inline uint16_t ByteSwap(uint16_t x) { +#if ZEN_COMPILER_MSC return _byteswap_ushort(x); +#else + return __builtin_bswap16(x); +#endif } inline uint32_t ByteSwap(uint32_t x) { +#if ZEN_COMPILER_MSC return _byteswap_ulong(x); +#else + return __builtin_bswap32(x); +#endif } inline uint64_t ByteSwap(uint64_t x) { +#if ZEN_COMPILER_MSC return _byteswap_uint64(x); +#else + return __builtin_bswap64(x); +#endif } inline uint16_t diff --git a/zencore/include/zencore/fmtutils.h b/zencore/include/zencore/fmtutils.h index fb5a08d56..29e2ae78a 100644 --- a/zencore/include/zencore/fmtutils.h +++ b/zencore/include/zencore/fmtutils.h @@ -43,7 +43,7 @@ struct fmt::formatter<std::filesystem::path> : formatter<string_view> auto format(const std::filesystem::path& Path, FormatContext& ctx) { zen::ExtendableStringBuilder<128> String; - WideToUtf8(Path.c_str(), String); + String << Path.u8string(); return formatter<string_view>::format(String.ToView(), ctx); } }; diff --git a/zencore/include/zencore/intmath.h b/zencore/include/zencore/intmath.h index 792b8b2b4..85447c17a 100644 --- a/zencore/include/zencore/intmath.h +++ b/zencore/include/zencore/intmath.h @@ -9,8 +9,46 @@ ////////////////////////////////////////////////////////////////////////// -#pragma intrinsic(_BitScanReverse) -#pragma intrinsic(_BitScanReverse64) +#if ZEN_COMPILER_MSC +# pragma intrinsic(_BitScanReverse) +# pragma intrinsic(_BitScanReverse64) +#else +inline uint8_t +_BitScanReverse(unsigned long* Index, uint32_t Mask) +{ + if (Mask == 0) + { + return 0; + } + + *Index = __builtin_clz(Mask); + return 1; +} + +inline uint8_t +_BitScanReverse64(unsigned long* Index, uint64_t Mask) +{ + if (Mask == 0) + { + return 0; + } + + *Index = __builtin_clzll(Mask); + return 0; +} + +inline uint8_t +_BitScanForward64(unsigned long* Index, uint64_t Mask) +{ + if (Mask == 0) + { + return 0; + } + + *Index = __builtin_ctzll(Mask); + return 0; +} +#endif namespace zen { @@ -121,8 +159,10 @@ IsPointerAligned(const void* Ptr, uint64_t Alignment) ////////////////////////////////////////////////////////////////////////// -#ifdef min -# error "Looks like you did #include <windows.h> -- use <zencore/windows.h> instead" +#if ZEN_PLATFORM_WINDOWS +# ifdef min +# error "Looks like you did #include <windows.h> -- use <zencore/windows.h> instead" +# endif #endif constexpr auto @@ -137,4 +177,8 @@ Max(auto x, auto y) return x > y ? x : y; } +////////////////////////////////////////////////////////////////////////// + +void intmath_forcelink(); // internal + } // namespace zen diff --git a/zencore/include/zencore/iohash.h b/zencore/include/zencore/iohash.h index aaa638684..fd0f4b2a7 100644 --- a/zencore/include/zencore/iohash.h +++ b/zencore/include/zencore/iohash.h @@ -8,6 +8,7 @@ #include <zencore/blake3.h> #include <zencore/memory.h> +#include <compare> #include <string_view> namespace zen { diff --git a/zencore/include/zencore/memory.h b/zencore/include/zencore/memory.h index 5a324955d..3cec0eb88 100644 --- a/zencore/include/zencore/memory.h +++ b/zencore/include/zencore/memory.h @@ -8,6 +8,8 @@ #include <zencore/thread.h> #include <algorithm> +#include <cstddef> +#include <cstring> #include <span> #include <vector> diff --git a/zencore/include/zencore/sharedbuffer.h b/zencore/include/zencore/sharedbuffer.h index b230c05b1..640c3fe74 100644 --- a/zencore/include/zencore/sharedbuffer.h +++ b/zencore/include/zencore/sharedbuffer.h @@ -12,6 +12,8 @@ namespace zen { +class SharedBuffer; + /** * Reference to a memory buffer with a single owner * diff --git a/zencore/include/zencore/string.h b/zencore/include/zencore/string.h index de2ca71d9..2b5f20f86 100644 --- a/zencore/include/zencore/string.h +++ b/zencore/include/zencore/string.h @@ -560,15 +560,17 @@ NiceRate(uint64_t Num, uint32_t DurationMilliseconds, const char* Unit = "B") if (DurationMilliseconds) { - NiceNumToBuffer(Num * 1000 / DurationMilliseconds, Buffer); + // Leave a little of 'Buffer' for the "Unit/s" suffix + std::span<char> BufferSpan(Buffer, sizeof(Buffer) - 8); + NiceNumToBuffer(Num * 1000 / DurationMilliseconds, BufferSpan); } else { - strcpy_s(Buffer, "0"); + strcpy(Buffer, "0"); } - strcat_s(Buffer, Unit); - strcat_s(Buffer, "/s"); + strncat(Buffer, Unit, 4); + strcat(Buffer, "/s"); return Buffer; } diff --git a/zencore/include/zencore/thread.h b/zencore/include/zencore/thread.h index 30d0c0897..b18da6031 100644 --- a/zencore/include/zencore/thread.h +++ b/zencore/include/zencore/thread.h @@ -4,6 +4,10 @@ #include "zencore.h" +#if !ZEN_PLATFORM_WINDOWS +# include <shared_mutex> +#endif + namespace zen { /** @@ -60,7 +64,11 @@ public: }; private: +#if ZEN_PLATFORM_WINDOWS void* m_Srw = nullptr; +#else + std::shared_mutex m_Mutex; +#endif }; /** Basic abstraction of a simple event synchronization mechanism (aka 'binary semaphore') diff --git a/zencore/include/zencore/timer.h b/zencore/include/zencore/timer.h index c9122eb44..eb284eaee 100644 --- a/zencore/include/zencore/timer.h +++ b/zencore/include/zencore/timer.h @@ -2,10 +2,16 @@ #pragma once -#include <intrin.h> -#include <stdint.h> #include "zencore.h" +#if ZEN_COMPILER_MSC +# include <intrin.h> +#elif ZEN_ARCH_X64 +# include <x86intrin.h> +#endif + +#include <stdint.h> + namespace zen { // High frequency timers diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 206046f0b..73446b447 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -10,24 +10,65 @@ // Platform // -#define ZEN_PLATFORM_WINDOWS 1 -#define ZEN_PLATFORM_LINUX 0 -#define ZEN_PLATFORM_MACOS 0 +#define ZEN_PLATFORM_WINDOWS 0 +#define ZEN_PLATFORM_LINUX 0 +#define ZEN_PLATFORM_MACOS 0 + +#ifdef _WIN32 +# undef ZEN_PLATFORM_WINDOWS +# define ZEN_PLATFORM_WINDOWS 1 +#elif defined(__linux__) +# undef ZEN_PLATFORM_LINUX +# define ZEN_PLATFORM_LINUX 1 +#elif defined(__APPLE__) +# undef ZEN_PLATFORM_MACOS +# define ZEN_PLATFORM_MACOS 1 +#endif ////////////////////////////////////////////////////////////////////////// // Compiler // -#ifdef _MSC_VER -# define ZEN_COMPILER_MSC 1 +#define ZEN_COMPILER_CLANG 0 +#define ZEN_COMPILER_MSC 0 +#define ZEN_COMPILER_GCC 0 + +// Clang can define __GNUC__ and/or _MSC_VER so we check for Clang first +#ifdef __clang__ +# undef ZEN_COMPILER_CLANG +# define ZEN_COMPILER_CLANG 1 +#elif defined(_MSC_VER) +# undef ZEN_COMPILER_MSC +# define ZEN_COMPILER_MSC 1 +#elif defined(__GNUC__) +# undef ZEN_COMPILER_GCC +# define ZEN_COMPILER_GCC 1 +#else +# error Unknown compiler #endif -#ifndef ZEN_COMPILER_MSC -# define ZEN_COMPILER_MSC 0 +// Check for C++20 support +#if !ZEN_PLATFORM_WINDOWS +# if ZEN_COMPILER_CLANG && __clang_major__ < 14 +# error LLVM-14 onwards required for complete C++20 support +# elif ZEN_COMPILER_GCC && __GNUC__ < 11 +# error GCC-11 onwards required for complete C++20 support +# endif #endif -#ifndef ZEN_COMPILER_CLANG -# define ZEN_COMPILER_CLANG 0 + +////////////////////////////////////////////////////////////////////////// +// Architecture +// + +#if defined(__amd64__) || defined(_M_X64) +# define ZEN_ARCH_X64 1 +# define ZEN_ARCH_ARM64 0 +#elif defined(__arm64__) || defined(_M_ARM64) +# define ZEN_ARCH_X64 0 +# define ZEN_ARCH_ARM64 1 +#else +# error Unknown architecture #endif ////////////////////////////////////////////////////////////////////////// @@ -58,7 +99,7 @@ public: AssertException(const char* Msg); ~AssertException(); - [[nodiscard]] virtual char const* what() const override { return m_Msg.c_str(); } + [[nodiscard]] virtual char const* what() const noexcept override { return m_Msg.c_str(); } private: std::string m_Msg; @@ -100,7 +141,12 @@ char (&ZenArrayCountHelper(const T (&)[N]))[N + 1]; ////////////////////////////////////////////////////////////////////////// -#define ZEN_NOINLINE __declspec(noinline) +#if ZEN_COMPILER_MSC +# define ZEN_NOINLINE __declspec(noinline) +#else +# define ZEN_NOINLINE __attribute__((noinline)) +#endif + #define ZEN_UNUSED(...) ((void)__VA_ARGS__) #define ZEN_NOT_IMPLEMENTED(...) ZEN_ASSERT(false) #define ZENCORE_API // Placeholder to allow DLL configs in the future diff --git a/zencore/intmath.cpp b/zencore/intmath.cpp new file mode 100644 index 000000000..4039a3b39 --- /dev/null +++ b/zencore/intmath.cpp @@ -0,0 +1,56 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <zencore/intmath.h> + +#include <doctest/doctest.h> + +namespace zen { + +////////////////////////////////////////////////////////////////////////// +// +// Testing related code follows... +// + +void +intmath_forcelink() +{ +} + +TEST_CASE("intmath") +{ + CHECK(FloorLog2(0x00) == 0); + CHECK(FloorLog2(0x01) == 0); + CHECK(FloorLog2(0x0f) == 3); + CHECK(FloorLog2(0x10) == 4); + CHECK(FloorLog2(0x11) == 4); + CHECK(FloorLog2(0x12) == 4); + CHECK(FloorLog2(0x22) == 5); + CHECK(FloorLog2(0x0001'0000) == 16); + CHECK(FloorLog2(0x0001'000f) == 16); + CHECK(FloorLog2(0x8000'0000) == 31); + + CHECK(FloorLog2_64(0x00ull) == 0); + CHECK(FloorLog2_64(0x01ull) == 0); + CHECK(FloorLog2_64(0x0full) == 3); + CHECK(FloorLog2_64(0x10ull) == 4); + CHECK(FloorLog2_64(0x11ull) == 4); + CHECK(FloorLog2_64(0x0001'0000ull) == 16); + CHECK(FloorLog2_64(0x0001'000full) == 16); + CHECK(FloorLog2_64(0x8000'0000ull) == 31); + CHECK(FloorLog2_64(0x0000'0001'0000'0000ull) == 32); + CHECK(FloorLog2_64(0x8000'0000'0000'0000ull) == 63); + + CHECK(CountLeadingZeros64(0x8000'0000'0000'0000ull) == 0); + CHECK(CountLeadingZeros64(0x0000'0000'0000'0000ull) == 64); + CHECK(CountLeadingZeros64(0x0000'0000'0000'0001ull) == 63); + CHECK(CountLeadingZeros64(0x0000'0000'8000'0000ull) == 32); + CHECK(CountLeadingZeros64(0x0000'0001'0000'0000ull) == 31); + + CHECK(CountTrailingZeros64(0x8000'0000'0000'0000ull) == 63); + CHECK(CountTrailingZeros64(0x0000'0000'0000'0000ull) == 64); + CHECK(CountTrailingZeros64(0x0000'0000'0000'0001ull) == 0); + CHECK(CountTrailingZeros64(0x0000'0000'8000'0000ull) == 31); + CHECK(CountTrailingZeros64(0x0000'0001'0000'0000ull) == 32); +} + +} // namespace zen diff --git a/zencore/memory.cpp b/zencore/memory.cpp index 63d61f5e1..25a8d4761 100644 --- a/zencore/memory.cpp +++ b/zencore/memory.cpp @@ -10,6 +10,33 @@ namespace zen { ////////////////////////////////////////////////////////////////////////// +static void* AlignedAllocImpl(size_t size, size_t alignment) +{ +#if ZEN_PLATFORM_WINDOWS + // return _aligned_malloc(size, alignment); // MSVC alternative + return _mm_malloc(size, alignment); +#else + // posix_memalign(&Ret, Alignment, Size); // Apple, AndroidApi<28 + return std::aligned_alloc(alignment, size); +#endif +} + +void AlignedFreeImpl(void* ptr) +{ + if (ptr == nullptr) + return; + +#if ZEN_PLATFORM_WINDOWS + // _aligned_free(ptr); MSVC alternative + _mm_free(ptr); +#else + // free(ptr) // Apple :) + std::free(ptr); +#endif +} + +////////////////////////////////////////////////////////////////////////// + MemoryArena::MemoryArena() { } @@ -21,14 +48,13 @@ MemoryArena::~MemoryArena() void* MemoryArena::Alloc(size_t size, size_t alignment) { - return _mm_malloc(size, alignment); + return AlignedAllocImpl(size, alignment); } void MemoryArena::Free(void* ptr) { - if (ptr) - _mm_free(ptr); + AlignedFreeImpl(ptr); } ////////////////////////////////////////////////////////////////////////// @@ -36,14 +62,13 @@ MemoryArena::Free(void* ptr) void* Memory::Alloc(size_t size, size_t alignment) { - return _mm_malloc(size, alignment); + return AlignedAllocImpl(size, alignment); } void Memory::Free(void* ptr) { - if (ptr) - _mm_free(ptr); + AlignedFreeImpl(ptr); } ////////////////////////////////////////////////////////////////////////// diff --git a/zencore/snapshot_manifest.cpp b/zencore/snapshot_manifest.cpp index 7d0769d13..87625fb7f 100644 --- a/zencore/snapshot_manifest.cpp +++ b/zencore/snapshot_manifest.cpp @@ -13,7 +13,9 @@ // Used for getting My Documents for default snapshot dir #include <ShlObj.h> -#pragma comment(lib, "shell32.lib") +#if ZEN_PLATFORM_WINDOWS +# pragma comment(lib, "shell32.lib") +#endif namespace zen { diff --git a/zencore/stream.cpp b/zencore/stream.cpp index bd925ebc4..34fff19bb 100644 --- a/zencore/stream.cpp +++ b/zencore/stream.cpp @@ -22,7 +22,7 @@ MemoryInStream::Read(void* buffer, size_t byteCount, uint64_t offset) const size_t needEnd = offset + byteCount; if (needEnd > m_Buffer.size()) - throw std::exception("read past end of file!"); // TODO: better exception + throw std::runtime_error("read past end of file!"); // TODO: better exception memcpy(buffer, m_Buffer.data() + offset, byteCount); } @@ -95,7 +95,11 @@ TextWriter& operator<<(TextWriter& writer, int8_t value) { char buffer[16]; +#if ZEN_PLATFORM_WINDOWS _itoa_s(value, buffer, 10); +#else + sprintf(buffer, "%d", value); +#endif writer << buffer; return writer; } @@ -104,7 +108,11 @@ TextWriter& operator<<(TextWriter& writer, int16_t value) { char buffer[16]; +#if ZEN_PLATFORM_WINDOWS _itoa_s(value, buffer, 10); +#else + sprintf(buffer, "%d", value); +#endif writer << buffer; return writer; } @@ -113,7 +121,11 @@ TextWriter& operator<<(TextWriter& writer, int32_t value) { char buffer[16]; +#if ZEN_PLATFORM_WINDOWS _itoa_s(value, buffer, 10); +#else + sprintf(buffer, "%d", value); +#endif writer << buffer; return writer; } @@ -122,7 +134,11 @@ TextWriter& operator<<(TextWriter& writer, int64_t value) { char buffer[32]; +#if ZEN_PLATFORM_WINDOWS _i64toa_s(value, buffer, sizeof buffer, 10); +#else + sprintf(buffer, "%" PRId64, value); +#endif writer << buffer; return writer; } @@ -131,7 +147,11 @@ TextWriter& operator<<(TextWriter& writer, uint8_t value) { char buffer[16]; +#if ZEN_PLATFORM_WINDOWS _ultoa_s(value, buffer, 10); +#else + sprintf(buffer, "%u", value); +#endif writer << buffer; return writer; } @@ -140,7 +160,11 @@ TextWriter& operator<<(TextWriter& writer, uint16_t value) { char buffer[16]; +#if ZEN_PLATFORM_WINDOWS _ultoa_s(value, buffer, 10); +#else + sprintf(buffer, "%u", value); +#endif writer << buffer; return writer; } @@ -149,7 +173,11 @@ TextWriter& operator<<(TextWriter& writer, uint32_t value) { char buffer[16]; +#if ZEN_PLATFORM_WINDOWS _ultoa_s(value, buffer, 10); +#else + sprintf(buffer, "%u", value); +#endif writer << buffer; return writer; } @@ -158,7 +186,11 @@ TextWriter& operator<<(TextWriter& writer, uint64_t value) { char buffer[32]; +#if ZEN_PLATFORM_WINDOWS _ui64toa_s(value, buffer, sizeof buffer, 10); +#else + sprintf(buffer, "%" PRIu64, value); +#endif writer << buffer; return writer; } diff --git a/zencore/string.cpp b/zencore/string.cpp index 21ba5b204..764b3de03 100644 --- a/zencore/string.cpp +++ b/zencore/string.cpp @@ -34,14 +34,14 @@ namespace zen { bool ToString(std::span<char> Buffer, uint64_t Num) { - snprintf(Buffer.data(), Buffer.size(), "%I64u", Num); + snprintf(Buffer.data(), Buffer.size(), "%" PRIu64, Num); return true; } bool ToString(std::span<char> Buffer, int64_t Num) { - snprintf(Buffer.data(), Buffer.size(), "%I64d", Num); + snprintf(Buffer.data(), Buffer.size(), "%" PRId64, Num); return true; } @@ -231,12 +231,12 @@ NiceNumGeneral(uint64_t Num, std::span<char> Buffer, NicenumFormat Format) switch (Format) { case kNicenumRaw: - return snprintf(Buffer.data(), Buffer.size(), "%llu", (uint64_t)Num); + return snprintf(Buffer.data(), Buffer.size(), "%" PRIu64, (uint64_t)Num); case kNicenumRawTime: if (Num > 0) { - return snprintf(Buffer.data(), Buffer.size(), "%llu", (uint64_t)Num); + return snprintf(Buffer.data(), Buffer.size(), "%" PRIu64, (uint64_t)Num); } else { @@ -275,7 +275,7 @@ NiceNumGeneral(uint64_t Num, std::span<char> Buffer, NicenumFormat Format) * If this is an even multiple of the base, always display * without any decimal precision. */ - return snprintf(Buffer.data(), Buffer.size(), "%llu%s", (uint64_t)n, u); + return snprintf(Buffer.data(), Buffer.size(), "%" PRIu64 "%s", (uint64_t)n, u); } else { @@ -437,7 +437,7 @@ template<typename C> [[noreturn]] void StringBuilderImpl<C>::Fail(const char* reason) { - throw std::exception(reason); + throw std::runtime_error(reason); } // Instantiate templates once diff --git a/zencore/thread.cpp b/zencore/thread.cpp index fa9da0258..598466bb4 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -5,33 +5,53 @@ #include <fmt/format.h> #include <zencore/except.h> #include <zencore/string.h> -#include <zencore/windows.h> -#include <thread> + +#if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> +#elif ZEN_PLATFORM_LINUX +# include <unistd.h> +#endif namespace zen { void RwLock::AcquireShared() { +#if ZEN_PLATFORM_WINDOWS AcquireSRWLockShared((PSRWLOCK)&m_Srw); +#else + m_Mutex.lock_shared(); +#endif } void RwLock::ReleaseShared() { +#if ZEN_PLATFORM_WINDOWS ReleaseSRWLockShared((PSRWLOCK)&m_Srw); +#else + m_Mutex.unlock_shared(); +#endif } void RwLock::AcquireExclusive() { +#if ZEN_PLATFORM_WINDOWS AcquireSRWLockExclusive((PSRWLOCK)&m_Srw); +#else + m_Mutex.lock(); +#endif } void RwLock::ReleaseExclusive() { +#if ZEN_PLATFORM_WINDOWS ReleaseSRWLockExclusive((PSRWLOCK)&m_Srw); +#else + m_Mutex.unlock(); +#endif } Event::Event() @@ -253,13 +273,21 @@ IsProcessRunning(int pid) int GetCurrentProcessId() { +#if ZEN_PLATFORM_WINDOWS return ::GetCurrentProcessId(); +#else + return getpid(); +#endif } void Sleep(int ms) { +#if ZEN_PLATFORM_WINDOWS ::Sleep(ms); +#else + usleep(ms * 1000U); +#endif } ////////////////////////////////////////////////////////////////////////// diff --git a/zencore/timer.cpp b/zencore/timer.cpp index ee8e1cf9c..08b5e06d2 100644 --- a/zencore/timer.cpp +++ b/zencore/timer.cpp @@ -3,26 +3,41 @@ #include <doctest/doctest.h> #include <zencore/thread.h> #include <zencore/timer.h> -#include <zencore/windows.h> +#if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> +#elif ZEN_PLATFORM_LINUX +# include <time.h> +# include <unistd.h> +#endif namespace zen { uint64_t GetHifreqTimerValue() { +#if ZEN_PLATFORM_WINDOWS LARGE_INTEGER li; QueryPerformanceCounter(&li); return li.QuadPart; +#else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t(ts.tv_sec) * 1000000ull) + (uint64_t(ts.tv_nsec) / 1000ull); +#endif } uint64_t internalGetHifreqTimerFrequency() { +#if ZEN_PLATFORM_WINDOWS LARGE_INTEGER li; QueryPerformanceFrequency(&li); return li.QuadPart; +#else + return 1000000ull; +#endif } static uint64_t qpcFreq = internalGetHifreqTimerFrequency(); @@ -56,7 +71,7 @@ TEST_CASE("Timer") { uint64_t s0 = GetHifreqTimerValue(); uint64_t t0 = GetCpuTimerValue(); - Sleep(1000); + zen::Sleep(1000); uint64_t s1 = GetHifreqTimerValue(); uint64_t t1 = GetCpuTimerValue(); // double r = double(t1 - t0) / (s1 - s0); diff --git a/zencore/zencore.cpp b/zencore/zencore.cpp index c2a57b653..c53fd218f 100644 --- a/zencore/zencore.cpp +++ b/zencore/zencore.cpp @@ -2,7 +2,13 @@ #include <zencore/zencore.h> +#if ZEN_PLATFORM_WINDOWS #include <zencore/windows.h> +#endif + +#if ZEN_PLATFORM_LINUX +#include <pthread.h> +#endif #include <zencore/blake3.h> #include <zencore/compactbinary.h> @@ -25,12 +31,26 @@ bool IsPointerToStack(const void* ptr) { +#if ZEN_PLATFORM_WINDOWS ULONG_PTR low, high; GetCurrentThreadStackLimits(&low, &high); const uintptr_t intPtr = reinterpret_cast<uintptr_t>(ptr); return (intPtr - low) < (high - low); +#elif ZEN_PLATFORM_LINUX + pthread_t self = pthread_self(); + + pthread_attr_t attr; + pthread_getattr_np(self, &attr); + + void* low; + size_t size; + pthread_attr_getstack(&attr, &low, &size); + + return (uintptr_t(ptr) - uintptr_t(low)) < uintptr_t(size); +#elif 0 +#endif } zen::AssertException::AssertException(const char* Msg) : m_Msg(Msg) @@ -65,6 +85,7 @@ zencore_forcelinktests() zen::blake3_forcelink(); zen::compositebuffer_forcelink(); zen::compress_forcelink(); + zen::intmath_forcelink(); zen::iobuffer_forcelink(); zen::memory_forcelink(); zen::refcount_forcelink(); diff --git a/zencore/zencore.vcxproj b/zencore/zencore.vcxproj index 4b5bba185..4f1e63670 100644 --- a/zencore/zencore.vcxproj +++ b/zencore/zencore.vcxproj @@ -160,6 +160,7 @@ <ClCompile Include="crc32.cpp" /> <ClCompile Include="except.cpp" /> <ClCompile Include="filesystem.cpp" /> + <ClCompile Include="intmath.cpp" /> <ClCompile Include="iohash.cpp" /> <ClCompile Include="logging.cpp" /> <ClCompile Include="md5.cpp" /> diff --git a/zencore/zencore.vcxproj.filters b/zencore/zencore.vcxproj.filters index 70c1cfb01..de3d915b8 100644 --- a/zencore/zencore.vcxproj.filters +++ b/zencore/zencore.vcxproj.filters @@ -71,6 +71,7 @@ <ClCompile Include="compositebuffer.cpp" /> <ClCompile Include="crc32.cpp" /> <ClCompile Include="logging.cpp" /> + <ClCompile Include="intmath.cpp" /> </ItemGroup> <ItemGroup> <Filter Include="CAS"> diff --git a/zenfs_common.props b/zenfs_common.props index f550ff929..67894b9e8 100644 --- a/zenfs_common.props +++ b/zenfs_common.props @@ -11,7 +11,7 @@ <WarningLevel>Level4</WarningLevel> <MultiProcessorCompilation>true</MultiProcessorCompilation> <TreatWarningAsError>true</TreatWarningAsError> - <PreprocessorDefinitions>_UNICODE;UNICODE;_WIN32_WINNT=0x0A00 ;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;_WIN32_WINNT=0x0A00 ;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <IgnoreSpecificDefaultLibraries>msvcrt</IgnoreSpecificDefaultLibraries> |