aboutsummaryrefslogtreecommitdiff
path: root/src/zencore
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-12-19 12:06:13 +0100
committerGitHub <[email protected]>2023-12-19 12:06:13 +0100
commit519d942d809e740a3b1fe5a1f6a57a4cfe43408b (patch)
tree9b3c084e21bb7fd5e6bb3335e890647062d0703b /src/zencore
parentadded mimalloc_hooks (diff)
parentensure we can build without trace (#619) (diff)
downloadzen-273-integrated-memory-tracking.tar.xz
zen-273-integrated-memory-tracking.zip
Merge branch 'main' into 273-integrated-memory-tracking273-integrated-memory-tracking
Diffstat (limited to 'src/zencore')
-rw-r--r--src/zencore/compactbinary.cpp52
-rw-r--r--src/zencore/compress.cpp4
-rw-r--r--src/zencore/filesystem.cpp12
-rw-r--r--src/zencore/include/zencore/compactbinary.h36
-rw-r--r--src/zencore/include/zencore/compactbinarybuilder.h1
-rw-r--r--src/zencore/include/zencore/compactbinaryvalidation.h1
-rw-r--r--src/zencore/include/zencore/iobuffer.h17
-rw-r--r--src/zencore/include/zencore/string.h7
-rw-r--r--src/zencore/include/zencore/trace.h1
-rw-r--r--src/zencore/iobuffer.cpp4
-rw-r--r--src/zencore/jobqueue.cpp7
-rw-r--r--src/zencore/memory.cpp26
-rw-r--r--src/zencore/thread.cpp13
-rw-r--r--src/zencore/workthreadpool.cpp4
-rw-r--r--src/zencore/zencore.cpp6
15 files changed, 146 insertions, 45 deletions
diff --git a/src/zencore/compactbinary.cpp b/src/zencore/compactbinary.cpp
index 9152a8bfc..6677b5a61 100644
--- a/src/zencore/compactbinary.cpp
+++ b/src/zencore/compactbinary.cpp
@@ -2463,6 +2463,58 @@ TEST_CASE("json.uson")
}
}
+//////////////////////////////////////////////////////////////////////////
+
+TEST_SUITE_BEGIN("core.datetime");
+
+TEST_CASE("core.datetime.compare")
+{
+ DateTime T1(2000, 12, 13);
+ DateTime T2(2000, 12, 14);
+ CHECK(T1 < T2);
+ CHECK(T2 > T1);
+ CHECK(T1 == T1);
+ CHECK(T1 != T2);
+ CHECK(T1 >= T1);
+ CHECK(T2 >= T1);
+ CHECK(T1 <= T1);
+ CHECK(T1 <= T2);
+}
+
+TEST_CASE("core.datetime.add")
+{
+ DateTime T1(2000, 12, 13);
+ DateTime T2(2000, 12, 14);
+ TimeSpan dT = T2 - T1;
+ TimeSpan dT1 = T1 - T1;
+
+ CHECK(T1 + dT == T2);
+ CHECK(dT + T1 == T2);
+ CHECK(dT + T1 - T2 == dT1);
+}
+
+TEST_SUITE_END();
+
+TEST_SUITE_BEGIN("core.timespan");
+
+TEST_CASE("core.timespan.compare")
+{
+ TimeSpan T1(1000);
+ TimeSpan T2(1001);
+ CHECK(T1 < T2);
+ CHECK(T2 > T1);
+ CHECK(T1 == T1);
+ CHECK(T1 != T2);
+ CHECK(T1 >= T1);
+ CHECK(T2 >= T1);
+ CHECK(T1 <= T1);
+ CHECK(T1 <= T2);
+}
+
+TEST_SUITE_END();
+
+//////////////////////////////////////////////////////////////////////////
+
#endif
} // namespace zen
diff --git a/src/zencore/compress.cpp b/src/zencore/compress.cpp
index 2362d8e78..c41bdac42 100644
--- a/src/zencore/compress.cpp
+++ b/src/zencore/compress.cpp
@@ -1268,7 +1268,7 @@ CompressedBuffer::FromCompressed(SharedBuffer&& InCompressedData, IoHash& OutRaw
CompressedBuffer
CompressedBuffer::FromCompressedNoValidate(IoBuffer&& InCompressedData)
{
- if (InCompressedData.GetSize() <= sizeof(detail::BufferHeader))
+ if (InCompressedData.GetSize() < sizeof(detail::BufferHeader))
{
return CompressedBuffer();
}
@@ -1280,7 +1280,7 @@ CompressedBuffer::FromCompressedNoValidate(IoBuffer&& InCompressedData)
CompressedBuffer
CompressedBuffer::FromCompressedNoValidate(CompositeBuffer&& InCompressedData)
{
- if (InCompressedData.GetSize() <= sizeof(detail::BufferHeader))
+ if (InCompressedData.GetSize() < sizeof(detail::BufferHeader))
{
return CompressedBuffer();
}
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index a0ff3793e..36195f7c7 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -1287,12 +1287,12 @@ PathFromHandle(void* NativeHandle, std::error_code& Ec)
{
if (NativeHandle == nullptr)
{
- return std::filesystem::path();
+ return "<error handle 'nullptr'>";
}
#if ZEN_PLATFORM_WINDOWS
if (NativeHandle == INVALID_HANDLE_VALUE)
{
- return std::filesystem::path();
+ return "<error handle 'invalid handle'>";
}
auto GetFinalPathNameByHandleWRetry =
@@ -1329,7 +1329,7 @@ PathFromHandle(void* NativeHandle, std::error_code& Ec)
if (Error != ERROR_SUCCESS)
{
Ec = MakeErrorCodeFromLastError();
- return std::filesystem::path();
+ return fmt::format("<error handle '{}'>", Ec.message());
}
if (RequiredLengthIncludingNul < PathDataSize)
@@ -1346,7 +1346,7 @@ PathFromHandle(void* NativeHandle, std::error_code& Ec)
if (Error != ERROR_SUCCESS)
{
Ec = MakeErrorCodeFromLastError();
- return std::filesystem::path();
+ return fmt::format("<error handle '{}'>", Ec.message());
}
ZEN_UNUSED(FinalLength);
return FullPath;
@@ -1360,7 +1360,7 @@ PathFromHandle(void* NativeHandle, std::error_code& Ec)
if (BytesRead <= 0)
{
Ec = MakeErrorCodeFromLastError();
- return {};
+ return fmt::format("<error handle '{}'>", Ec.message());
}
Link[BytesRead] = '\0';
@@ -1371,7 +1371,7 @@ PathFromHandle(void* NativeHandle, std::error_code& Ec)
if (fcntl(Fd, F_GETPATH, Path) < 0)
{
Ec = MakeErrorCodeFromLastError();
- return {};
+ return fmt::format("<error handle '{}'>", Ec.message());
}
return Path;
diff --git a/src/zencore/include/zencore/compactbinary.h b/src/zencore/include/zencore/compactbinary.h
index cb032e34a..675e2a8d4 100644
--- a/src/zencore/include/zencore/compactbinary.h
+++ b/src/zencore/include/zencore/compactbinary.h
@@ -26,12 +26,13 @@
namespace zen {
-class CbObjectView;
class CbArrayView;
+class CbObjectView;
+class CbValue;
+class CompressedBuffer;
class BinaryReader;
class BinaryWriter;
-class CompressedBuffer;
-class CbValue;
+class TimeSpan;
class DateTime
{
@@ -58,7 +59,11 @@ public:
void GetDate(int& Year, int& Month, int& Day) const;
inline bool operator==(const DateTime& Rhs) const { return Ticks == Rhs.Ticks; }
- inline auto operator<=>(const DateTime& Rhs) const { return Ticks - Rhs.Ticks; }
+ inline auto operator<=>(const DateTime& Rhs) const = default;
+
+ friend inline TimeSpan operator-(const DateTime& Lhs, const DateTime& Rhs);
+ friend inline DateTime operator+(const DateTime& Lhs, const TimeSpan& Rhs);
+ friend inline DateTime operator+(const TimeSpan& Lhs, const DateTime& Rhs);
std::string ToString(const char* Format) const;
std::string ToIso8601() const;
@@ -78,7 +83,7 @@ public:
inline uint64_t GetTicks() const { return Ticks; }
inline bool operator==(const TimeSpan& Rhs) const { return Ticks == Rhs.Ticks; }
- inline auto operator<=>(const TimeSpan& Rhs) const { return Ticks - Rhs.Ticks; }
+ inline auto operator<=>(const TimeSpan& Rhs) const = default;
/**
* Time span related constants.
@@ -136,12 +141,33 @@ public:
ZENCORE_API std::string ToString(const char* Format) const;
ZENCORE_API std::string ToString() const;
+ friend inline DateTime operator+(const DateTime& Lhs, const TimeSpan& Rhs);
+ friend inline DateTime operator+(const TimeSpan& Lhs, const DateTime& Rhs);
+
private:
void Set(int Days, int Hours, int Minutes, int Seconds, int FractionNano);
uint64_t Ticks;
};
+inline TimeSpan
+operator-(const DateTime& Lhs, const DateTime& Rhs)
+{
+ return TimeSpan(Lhs.Ticks - Rhs.Ticks);
+}
+
+inline DateTime
+operator+(const DateTime& Lhs, const TimeSpan& Rhs)
+{
+ return DateTime(Lhs.Ticks + Rhs.Ticks);
+}
+
+inline DateTime
+operator+(const TimeSpan& Lhs, const DateTime& Rhs)
+{
+ return DateTime(Lhs.Ticks + Rhs.Ticks);
+}
+
//////////////////////////////////////////////////////////////////////////
/**
diff --git a/src/zencore/include/zencore/compactbinarybuilder.h b/src/zencore/include/zencore/compactbinarybuilder.h
index dcb767d96..9c81cf490 100644
--- a/src/zencore/include/zencore/compactbinarybuilder.h
+++ b/src/zencore/include/zencore/compactbinarybuilder.h
@@ -10,7 +10,6 @@
#include <zencore/enumflags.h>
#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
-#include <zencore/sha1.h>
#include <atomic>
#include <memory>
diff --git a/src/zencore/include/zencore/compactbinaryvalidation.h b/src/zencore/include/zencore/compactbinaryvalidation.h
index b23c6d51d..ddecc8a38 100644
--- a/src/zencore/include/zencore/compactbinaryvalidation.h
+++ b/src/zencore/include/zencore/compactbinaryvalidation.h
@@ -9,7 +9,6 @@
#include <zencore/enumflags.h>
#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
-#include <zencore/sha1.h>
#include <gsl/gsl-lite.hpp>
diff --git a/src/zencore/include/zencore/iobuffer.h b/src/zencore/include/zencore/iobuffer.h
index d891ed55b..b9e503354 100644
--- a/src/zencore/include/zencore/iobuffer.h
+++ b/src/zencore/include/zencore/iobuffer.h
@@ -337,11 +337,20 @@ public:
BorrowedFile
};
- inline IoBuffer() = default;
- inline IoBuffer(IoBuffer&& Rhs) noexcept = default;
- inline IoBuffer(const IoBuffer& Rhs) = default;
+ inline IoBuffer() = default;
+ inline IoBuffer(IoBuffer&& Rhs) noexcept
+ {
+ m_Core.Swap(Rhs.m_Core);
+ Rhs.m_Core = NullBufferCore;
+ }
+ inline IoBuffer(const IoBuffer& Rhs) = default;
inline IoBuffer& operator=(const IoBuffer& Rhs) = default;
- inline IoBuffer& operator=(IoBuffer&& Rhs) noexcept = default;
+ inline IoBuffer& operator =(IoBuffer&& Rhs) noexcept
+ {
+ m_Core.Swap(Rhs.m_Core);
+ Rhs.m_Core = NullBufferCore;
+ return *this;
+ }
/** Create an uninitialized buffer of the given size
*/
diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h
index 3aec1647d..b0232d883 100644
--- a/src/zencore/include/zencore/string.h
+++ b/src/zencore/include/zencore/string.h
@@ -638,7 +638,12 @@ ToHexNumber(UnsignedIntegral auto Value, char* OutString)
bool
ParseHexNumber(const std::string_view HexString, UnsignedIntegral auto& OutValue)
{
- return ParseHexNumber(HexString.data(), sizeof(OutValue) * 2, (uint8_t*)&OutValue);
+ size_t ExpectedCharacterCount = sizeof(OutValue) * 2;
+ if (HexString.size() != ExpectedCharacterCount)
+ {
+ return false;
+ }
+ return ParseHexNumber(HexString.data(), ExpectedCharacterCount, (uint8_t*)&OutValue);
}
//////////////////////////////////////////////////////////////////////////
diff --git a/src/zencore/include/zencore/trace.h b/src/zencore/include/zencore/trace.h
index 2d4c1e610..89e4b76bf 100644
--- a/src/zencore/include/zencore/trace.h
+++ b/src/zencore/include/zencore/trace.h
@@ -35,6 +35,7 @@ bool TraceStop();
#else
#define ZEN_TRACE_CPU(x)
+#define ZEN_TRACE_CPU_FLUSH(x)
#endif // ZEN_WITH_TRACE
diff --git a/src/zencore/iobuffer.cpp b/src/zencore/iobuffer.cpp
index 912f9ce4e..80d0f4ee4 100644
--- a/src/zencore/iobuffer.cpp
+++ b/src/zencore/iobuffer.cpp
@@ -209,6 +209,8 @@ IoBufferExtendedCore::~IoBufferExtendedCore()
uint64_t MapSize = ~uint64_t(uintptr_t(m_MmapHandle));
munmap(m_MappedPointer, MapSize);
#endif
+
+ m_DataPtr = nullptr; // prevent any buffer deallocation attempts
}
const uint32_t LocalFlags = m_Flags.load(std::memory_order_relaxed);
@@ -244,8 +246,6 @@ IoBufferExtendedCore::~IoBufferExtendedCore()
ZEN_WARN("Error reported on file handle close, reason '{}'", GetLastErrorAsString());
}
}
-
- m_DataPtr = nullptr;
}
static constexpr size_t MappingLockCount = 128;
diff --git a/src/zencore/jobqueue.cpp b/src/zencore/jobqueue.cpp
index 1755b9fe9..4bcc5c885 100644
--- a/src/zencore/jobqueue.cpp
+++ b/src/zencore/jobqueue.cpp
@@ -422,8 +422,10 @@ TEST_CASE("JobQueue")
{
JobsLatch.AddCount(1);
Pool.ScheduleWork([&Queue, &JobsLatch, I]() {
- auto _ = MakeGuard([&JobsLatch]() { JobsLatch.CountDown(); });
- auto Id = Queue->QueueJob(fmt::format("busy {}", I), [&](JobContext& Context) {
+ auto _ = MakeGuard([&JobsLatch]() { JobsLatch.CountDown(); });
+ JobsLatch.AddCount(1);
+ auto Id = Queue->QueueJob(fmt::format("busy {}", I), [&JobsLatch, I](JobContext& Context) {
+ auto $ = MakeGuard([&JobsLatch]() { JobsLatch.CountDown(); });
if (Context.IsCancelled())
{
return;
@@ -523,7 +525,6 @@ TEST_CASE("JobQueue")
}
JobsLatch.Wait();
}
-
#endif
} // namespace zen
diff --git a/src/zencore/memory.cpp b/src/zencore/memory.cpp
index 546296b10..808c9fcb6 100644
--- a/src/zencore/memory.cpp
+++ b/src/zencore/memory.cpp
@@ -7,13 +7,12 @@
#include <zencore/testing.h>
#include <zencore/zencore.h>
-#if ZEN_PLATFORM_WINDOWS
-# include <malloc.h>
+#include <cstdlib>
+
+#if ZEN_USE_MIMALLOC
ZEN_THIRD_PARTY_INCLUDES_START
# include <mimalloc.h>
ZEN_THIRD_PARTY_INCLUDES_END
-#else
-# include <cstdlib>
#endif
namespace zen {
@@ -23,16 +22,15 @@ namespace zen {
static void*
AlignedAllocImpl(size_t Size, size_t Alignment)
{
-#if ZEN_PLATFORM_WINDOWS
-# if ZEN_USE_MIMALLOC && 0 /* this path is not functional */
- return mi_aligned_alloc(Alignment, Size);
-# else
- return _aligned_malloc(Size, Alignment);
-# endif
-#else
// aligned_alloc() states that size must be a multiple of alignment. Some
// platforms return null if this requirement isn't met.
Size = (Size + Alignment - 1) & ~(Alignment - 1);
+
+#if ZEN_USE_MIMALLOC
+ return mi_aligned_alloc(Alignment, Size);
+#elif ZEN_PLATFORM_WINDOWS
+ return _aligned_malloc(Size, Alignment);
+#else
return std::aligned_alloc(Alignment, Size);
#endif
}
@@ -43,12 +41,10 @@ AlignedFreeImpl(void* ptr)
if (ptr == nullptr)
return;
-#if ZEN_PLATFORM_WINDOWS
-# if ZEN_USE_MIMALLOC && 0 /* this path is not functional */
+#if ZEN_USE_MIMALLOC
return mi_free(ptr);
-# else
+#elif ZEN_PLATFORM_WINDOWS
_aligned_free(ptr);
-# endif
#else
std::free(ptr);
#endif
diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp
index 149a0d781..cb3aced33 100644
--- a/src/zencore/thread.cpp
+++ b/src/zencore/thread.cpp
@@ -156,6 +156,7 @@ Event::Event()
auto* Inner = new EventInner();
Inner->bSet = bInitialState;
m_EventHandle = Inner;
+ std::atomic_thread_fence(std::memory_order_release);
#endif
}
@@ -170,12 +171,13 @@ Event::Set()
#if ZEN_USE_WINDOWS_EVENTS
SetEvent(m_EventHandle);
#else
- auto* Inner = (EventInner*)m_EventHandle;
+ std::atomic_thread_fence(std::memory_order_acquire);
+ auto* Inner = (EventInner*)m_EventHandle;
{
std::unique_lock Lock(Inner->Mutex);
Inner->bSet.store(true);
+ Inner->CondVar.notify_all();
}
- Inner->CondVar.notify_all();
#endif
}
@@ -185,6 +187,7 @@ Event::Reset()
#if ZEN_USE_WINDOWS_EVENTS
ResetEvent(m_EventHandle);
#else
+ std::atomic_thread_fence(std::memory_order_acquire);
auto* Inner = (EventInner*)m_EventHandle;
{
std::unique_lock Lock(Inner->Mutex);
@@ -198,15 +201,18 @@ Event::Close()
{
#if ZEN_USE_WINDOWS_EVENTS
CloseHandle(m_EventHandle);
+ m_EventHandle = nullptr;
#else
+ std::atomic_thread_fence(std::memory_order_acquire);
auto* Inner = (EventInner*)m_EventHandle;
{
std::unique_lock Lock(Inner->Mutex);
Inner->bSet.store(true);
}
+ m_EventHandle = nullptr;
+ std::atomic_thread_fence(std::memory_order_release);
delete Inner;
#endif
- m_EventHandle = nullptr;
}
bool
@@ -226,6 +232,7 @@ Event::Wait(int TimeoutMs)
return (Result == WAIT_OBJECT_0);
#else
+ std::atomic_thread_fence(std::memory_order_acquire);
auto* Inner = reinterpret_cast<EventInner*>(m_EventHandle);
if (Inner->bSet.load())
diff --git a/src/zencore/workthreadpool.cpp b/src/zencore/workthreadpool.cpp
index 6ff6463dd..16b2310ff 100644
--- a/src/zencore/workthreadpool.cpp
+++ b/src/zencore/workthreadpool.cpp
@@ -132,7 +132,9 @@ struct WorkerThreadPool::Impl
Impl(int InThreadCount, std::string_view WorkerThreadBaseName) : m_WorkerThreadBaseName(WorkerThreadBaseName)
{
+# if ZEN_WITH_TRACE
trace::ThreadGroupBegin(m_WorkerThreadBaseName.c_str());
+# endif
zen::Latch WorkerLatch{InThreadCount};
@@ -143,7 +145,9 @@ struct WorkerThreadPool::Impl
WorkerLatch.Wait();
+# if ZEN_WITH_TRACE
trace::ThreadGroupEnd();
+# endif
}
~Impl()
diff --git a/src/zencore/zencore.cpp b/src/zencore/zencore.cpp
index 3b938a6ef..8dd687fbd 100644
--- a/src/zencore/zencore.cpp
+++ b/src/zencore/zencore.cpp
@@ -36,6 +36,8 @@
#include <fmt/format.h>
+#include <atomic>
+
namespace zen::assert {
void
@@ -103,8 +105,8 @@ IsInteractiveSession()
//////////////////////////////////////////////////////////////////////////
-static int s_ApplicationExitCode = 0;
-static bool s_ApplicationExitRequested;
+static std::atomic_int s_ApplicationExitCode{0};
+static std::atomic_bool s_ApplicationExitRequested{false};
bool
IsApplicationExitRequested()