diff --git a/Include/Aurora/Memory/ByteBuffer.hpp b/Include/Aurora/Memory/ByteBuffer.hpp index f3b40a89..bbc77f66 100644 --- a/Include/Aurora/Memory/ByteBuffer.hpp +++ b/Include/Aurora/Memory/ByteBuffer.hpp @@ -432,7 +432,7 @@ namespace Aurora::Memory // String API - inline bool WriteString(const AuString &string, EStringType type = EStringType::eStringDword, Locale::ECodePage codepage = Locale::ECodePage::eUTF8); + inline bool WriteString(std::string_view string, EStringType type = EStringType::eStringDword, Locale::ECodePage codepage = Locale::ECodePage::eUTF8); inline bool ReadString(AuString &string, EStringType type = EStringType::eStringDword, Locale::ECodePage codepage = Locale::ECodePage::eUTF8); // Copy, concat, etc diff --git a/Include/Aurora/Memory/ByteBuffer_Strings.inl b/Include/Aurora/Memory/ByteBuffer_Strings.inl index 5eeee0f1..f5dd91e6 100644 --- a/Include/Aurora/Memory/ByteBuffer_Strings.inl +++ b/Include/Aurora/Memory/ByteBuffer_Strings.inl @@ -14,7 +14,7 @@ namespace Aurora::Memory { - bool ByteBuffer::WriteString(const AuString &string, EStringType type, Locale::ECodePage codepage) + bool ByteBuffer::WriteString(std::string_view string, EStringType type, Locale::ECodePage codepage) { ByteBufferPushWriteState a(*this); AuStreamReadWrittenPair_t len {}; @@ -22,7 +22,7 @@ namespace Aurora::Memory if (codepage != Locale::ECodePage::eUTF8) { - len = Aurora::Locale::Encoding::EncodeUTF8(string, {}, codepage); + len = Aurora::Locale::Encoding::EncodeUTF8(Memory::MemoryViewRead { string.data(), string.length() }, { }, codepage); if (len == AuStreamReadWrittenPair_t {0, 0}) { return false; @@ -41,7 +41,7 @@ namespace Aurora::Memory return false; } - len = Aurora::Locale::Encoding::EncodeUTF8(string, writeView, codepage); + len = Aurora::Locale::Encoding::EncodeUTF8(Memory::MemoryViewRead { string.data(), string.length() }, writeView, codepage); if (len == AuStreamReadWrittenPair_t {0, 0}) { return false; diff --git a/Include/Aurora/Time/Clock.hpp b/Include/Aurora/Time/Clock.hpp deleted file mode 100644 index 2eed4479..00000000 --- a/Include/Aurora/Time/Clock.hpp +++ /dev/null @@ -1,139 +0,0 @@ -/*** - Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. - - File: Clock.hpp - Date: 2021-6-10 - Author: Reece -***/ -#pragma once - -#include "ETimezoneShift.hpp" -#include "TM.hpp" - -namespace Aurora::Time -{ - /** - Converts milliseconds from the Aurora epoch to a civil timestamp structure - similar to or of std::tm - */ - AUKN_SYM tm ToCivilTime(AuInt64 time, bool UTC = true); - - /** - Converts civil time to milliseconds from the Aurora epoch - */ - AUKN_SYM AuInt64 FromCivilTime(const tm &time, bool UTC = true); - - - /** - Normalizes a civil data structure with respect to UTC, given the two input parameters 'in' civil and 'shiftFrom' timezone hint - */ - AUKN_SYM tm NormalizeCivilTimezone(const tm &in, ETimezoneShift shiftFrom = ETimezoneShift::eUTC); - - /** - Translates the Aurora epoch to the standard unix epoch - */ - AUKN_SYM AuInt64 ConvertAuroraToUnixMS(AuInt64 in); - - /** - Translates the Aurora epoch to the standard unix epoch - */ - AUKN_SYM AuInt64 ConvertAuroraToUnixNS(AuInt64 in); - - /** - Translates a standard unix epoch to the Aurora epoch - */ - AUKN_SYM AuInt64 ConvertUnixToAuroraMS(AuInt64 in); - - /** - Translates a standard unix epoch to the Aurora epoch - */ - AUKN_SYM AuInt64 ConvertUnixToAuroraNS(AuInt64 in); - - /** - Retrieves wall clock in milliseconds from the Aurora epoch - */ - AUKN_SYM AuInt64 CurrentClockMS(); - - /** - Retrieves wall clock in nanoseconds from the Aurora epoch - */ - AUKN_SYM AuInt64 CurrentClockNS(); - - /** - * @brief Steady clock in jiffies - * @return - */ - AUKN_SYM AuUInt64 SteadyClock(); - - /** - Returns a steady system clock of SteadyClockJiffies() with an undefined epoch. - - These values should be used to drive thread primitives, IO time, and tick delta. - On a modern plaform, these should be affected by the users' calendar or NTP. - On stinkier platforms, who cares if we can run mostly bug free with an assumed-sane wall-clock, right? - */ - AUKN_SYM AuUInt64 SteadyClockMS(); - - /** - * @brief - * @return - */ - AUKN_SYM AuUInt64 SteadyClockNS(); - - /** - Retrieves the freqency of jiffies per second - */ - AUKN_SYM AuUInt64 SteadyClockJiffies(); - - - /** - Returns a high resolution count of jiffies with an undefined epoch from a - high resolution clock. - - These values should be used to drive benchmarks. - These values should not nor can be accurately converted meaningfully - */ - AUKN_SYM AuUInt64 HighResClock(); - AUKN_SYM AuUInt64 HighResClockMS(); - AUKN_SYM AuUInt64 HighResClockNS(); - - /** - Retrieves the freqency of jiffies per second - */ - AUKN_SYM AuUInt64 HighResClockJiffies(); - - /** - Let's say you're fucked and you need a ball park figure. - Enjoy... - */ - AUKN_SYM AuUInt64 ConvertInternalToAuroraEpochMS(AuUInt64 in); - AUKN_SYM AuUInt64 ConvertInternalToAuroraEpochNS(AuUInt64 in); - - /** - Converts seconds from the Aurora epoch to time_t - */ - AUKN_SYM time_t SToCTime(AuInt64 time); - - /** - Converts nanoseconds from the Aurora epoch to time_t - */ - AUKN_SYM time_t NSToCTime(AuInt64 time); - - /** - Converts milliseconds from the Aurora epoch to time_t - */ - AUKN_SYM time_t MSToCTime(AuInt64 time); - - AUKN_SYM AuInt64 CTimeToMS(time_t time); - - /** - Retrieves the freqency as a fraction of: jiffies per second / 1 * nanoseconds in a second - */ - AUKN_SYM double CPUFrequencyDeltaNS(); - - /** - Retrieves the freqency as a fraction of: jiffies per second / 1 * milliseconds in a second - */ - AUKN_SYM double CPUFrequencyDeltaMS(); - -} \ No newline at end of file diff --git a/Include/Aurora/Time/DebugBenchmark.hpp b/Include/Aurora/Time/DebugBenchmark.hpp index 2c6680be..decb4485 100644 --- a/Include/Aurora/Time/DebugBenchmark.hpp +++ b/Include/Aurora/Time/DebugBenchmark.hpp @@ -11,40 +11,39 @@ namespace Aurora::Time { -#if ((defined(AU_FORCE_BENCHMARK) || defined(DEBUG) || defined(STAGING)) && (!defined(AU_FORCE_NOBENCHMARK))) +#if ((defined(AU_FORCE_BENCHMARK) || defined(AU_CFG_ID_DEBUG) || defined(AU_CFG_ID_INTERNAL)) && (!defined(AU_FORCE_NOBENCHMARK))) - class DebugBenchmark + struct DebugBenchmark { - public: - DebugBenchmark(AuString message) : message_(message) {} + inline DebugBenchmark(AuString &&message) : message_(AuMove(message)) + { + this->stopwatch_.Start(); + } - ~DebugBenchmark() + inline ~DebugBenchmark() { Finish(); } - void Finish() + inline void Finish() { - if (AuExchange(finished_, true)) return; - auto time = timer_.End(); - Aurora::Logging::LogDbg("[Benchmark] {} took {}", message_, ConvertNSToTimescale(time)); + auto uEndNS = this->stopwatch_.EndNS(); + Aurora::Logging::LogDbg("[Benchmark] {} took {}", message_, ConvertNSToTimescale(uEndNS)); } private: - TimerHighRes timer_; - bool finished_ {}; + Stopwatch stopwatch_; AuString message_; }; #else - class DebugBenchmark + struct DebugBenchmark { - public: template DebugBenchmark(T... args) {} - void Finish() {} + inline void Finish() {} }; #endif diff --git a/Include/Aurora/Time/EClock.hpp b/Include/Aurora/Time/EClock.hpp new file mode 100644 index 00000000..ed21f1e8 --- /dev/null +++ b/Include/Aurora/Time/EClock.hpp @@ -0,0 +1,17 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: EClock.hpp + Date: 2023-3-21 + Author: Reece +***/ +#pragma once + +namespace Aurora::Time +{ + AUE_DEFINE(EClock, ( + eWall, + eSteady, + eProcessTime + )) +} \ No newline at end of file diff --git a/Include/Aurora/Time/ExtendedTimer.hpp b/Include/Aurora/Time/ExtendedTimer.hpp new file mode 100644 index 00000000..e69de29b diff --git a/Include/Aurora/Time/IClock.hpp b/Include/Aurora/Time/IClock.hpp new file mode 100644 index 00000000..0a8b5cfe --- /dev/null +++ b/Include/Aurora/Time/IClock.hpp @@ -0,0 +1,19 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: IClock.hpp + Date: 2023-3-21 + Author: Reece +***/ +#pragma once + +namespace Aurora::Time +{ + struct IClock + { + virtual EClock GetType() = 0; + virtual AuUInt64 GetHertz() = 0; + virtual AuUInt64 NowNS() = 0; + virtual AuUInt64 NowMS() = 0; + }; +} \ No newline at end of file diff --git a/Include/Aurora/Time/Stopwatch.hpp b/Include/Aurora/Time/Stopwatch.hpp new file mode 100644 index 00000000..7aa71ee3 --- /dev/null +++ b/Include/Aurora/Time/Stopwatch.hpp @@ -0,0 +1,53 @@ +/*** + Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: Stopwatch.hpp + Date: 2021-6-10 + Author: Reece +***/ +#pragma once + +namespace Aurora::Time +{ + AUKN_SYM AuUInt64 SteadyClockNS(); + + struct Stopwatch + { + inline Stopwatch() + { + Start(); + } + + inline ~Stopwatch() + { + + } + + inline void Start() + { + this->start_ = SteadyClockNS(); + } + + inline void Reset() + { + this->start_ = SteadyClockNS(); + this->end_ = 0; + } + + inline AuUInt64 EndNS() + { + if (!this->end_) this->end_ = SteadyClockNS(); + return this->end_ - this->start_; + } + + inline AuUInt64 EndMS() + { + if (!this->end_) this->end_ = SteadyClockNS(); + return AuNSToMS(this->end_ - this->start_); + } + + private: + AuUInt64 start_; + AuUInt64 end_; + }; +} \ No newline at end of file diff --git a/Include/Aurora/Time/Time.hpp b/Include/Aurora/Time/Time.hpp index d365d486..4de759d1 100644 --- a/Include/Aurora/Time/Time.hpp +++ b/Include/Aurora/Time/Time.hpp @@ -2,28 +2,161 @@ Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Time.hpp - Date: 2021-6-9 + Date: 2021-6-10 Author: Reece ***/ #pragma once -#include -#include +#include "_Time.hpp" namespace Aurora::Time { - static AuString ConvertMSToTimescale(AuUInt32 ms) - { - return Locale::ConvertMSToTimescale(ms); - } + /** + Converts milliseconds from the Aurora epoch to a civil timestamp structure + similar to or of std::tm + */ + AUKN_SYM tm ToCivilTime(AuInt64 time, bool bIsUTC = true); - static AuString ConvertNSToTimescale(AuUInt64 ns) - { - return Locale::ConvertNSToTimescale(ns); - } -} + /** + Converts civil time to milliseconds from the Aurora epoch + */ + AUKN_SYM AuInt64 FromCivilTime(const tm &time, bool bIsUTC = true); -#include "Clock.hpp" -#include "Timer.hpp" -#include "TimerHighRes.hpp" -#include "DebugBenchmark.hpp" \ No newline at end of file + + /** + Normalizes a civil data structure with respect to UTC, given the two input parameters 'in' civil and 'shiftFrom' timezone hint + */ + AUKN_SYM tm NormalizeCivilTimezone(const tm &in, ETimezoneShift shiftFrom = ETimezoneShift::eUTC); + + /** + Translates the Aurora epoch to the standard unix epoch + */ + AUKN_SYM AuInt64 ConvertAuroraToUnixMS(AuInt64 in); + + /** + Translates the Aurora epoch to the standard unix epoch + */ + AUKN_SYM AuInt64 ConvertAuroraToUnixNS(AuInt64 in); + + /** + Translates a standard unix epoch to the Aurora epoch + */ + AUKN_SYM AuInt64 ConvertUnixToAuroraMS(AuInt64 in); + + /** + Translates a standard unix epoch to the Aurora epoch + */ + AUKN_SYM AuInt64 ConvertUnixToAuroraNS(AuInt64 in); + + /** + Retrieves wall clock in milliseconds from the Aurora epoch + */ + AUKN_SYM AuInt64 CurrentClockMS(); + + /** + Retrieves wall clock in nanoseconds from the Aurora epoch + */ + AUKN_SYM AuInt64 CurrentClockNS(); + + /** + * @brief Steady clock in jiffies + * @return + */ + AUKN_SYM AuUInt64 SteadyClock(); + + /** + Returns a steady system clock of SteadyClockJiffies() with an undefined epoch. + + These values should be used to drive thread primitives, IO time, and tick delta. + On a modern plaform, these should be affected by the users' calendar or NTP. + On stinkier platforms, who cares if we can run mostly bug free with an assumed-sane wall-clock, right? + */ + AUKN_SYM AuUInt64 SteadyClockMS(); + + /** + * @brief + * @return + */ + AUKN_SYM AuUInt64 SteadyClockNS(); + + /** + Retrieves the freqency of jiffies per second + */ + AUKN_SYM AuUInt64 SteadyClockJiffies(); + + + /** + Returns a high resolution count of jiffies with an undefined epoch from a + high resolution clock. + + These values should be used to drive benchmarks. + These values should not nor can be accurately converted meaningfully + */ + AUKN_SYM AuUInt64 HighResClock(); + AUKN_SYM AuUInt64 HighResClockMS(); + AUKN_SYM AuUInt64 HighResClockNS(); + + /** + Retrieves the freqency of jiffies per second + */ + AUKN_SYM AuUInt64 HighResClockJiffies(); + + /** + Let's say you're fucked and you need a ball park figure. + Enjoy... + */ + AUKN_SYM AuUInt64 ConvertInternalToAuroraEpochMS(AuUInt64 in); + AUKN_SYM AuUInt64 ConvertInternalToAuroraEpochNS(AuUInt64 in); + + /** + Converts seconds from the Aurora epoch to time_t + */ + AUKN_SYM time_t SToCTime(AuInt64 time); + + /** + Converts nanoseconds from the Aurora epoch to time_t + */ + AUKN_SYM time_t NSToCTime(AuInt64 time); + + /** + Converts milliseconds from the Aurora epoch to time_t + */ + AUKN_SYM time_t MSToCTime(AuInt64 time); + + AUKN_SYM AuInt64 CTimeToMS(time_t time); + + /** + Retrieves the freqency as a fraction of: jiffies per second / 1 * nanoseconds in a second + */ + AUKN_SYM double CPUFrequencyDeltaNS(); + + /** + Retrieves the freqency as a fraction of: jiffies per second / 1 * milliseconds in a second + */ + AUKN_SYM double CPUFrequencyDeltaMS(); + + /** + * @brief + * @return + */ + AUKN_SYM AuSPtr GetWallClock(); + + /** + * @brief + * @return + */ + AUKN_SYM AuSPtr GetSteadyClock(); + + /** + * @brief + * @return + */ + AUKN_SYM AuSPtr GetProcessClock(); + + /** + * @brief + * @param clock + * @return + */ + AUKN_SYM AuSPtr GetClockFromEnum(EClock clock); +} \ No newline at end of file diff --git a/Include/Aurora/Time/Timer.hpp b/Include/Aurora/Time/Timer.hpp deleted file mode 100644 index b0cd14f4..00000000 --- a/Include/Aurora/Time/Timer.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/*** - Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. - - File: Timer.hpp - Date: 2021-6-10 - Author: Reece -***/ -#pragma once - -namespace Aurora::Time -{ - class Timer - { - public: - Timer() - { - Start(); - } - - void Start() - { - start_ = CurrentClockMS(); - } - - AuUInt64 End() - { - return CurrentClockMS() - start_; - } - - private: - AuUInt64 start_; - }; -} \ No newline at end of file diff --git a/Include/Aurora/Time/TimerHighRes.hpp b/Include/Aurora/Time/TimerHighRes.hpp deleted file mode 100644 index 1d146eb5..00000000 --- a/Include/Aurora/Time/TimerHighRes.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/*** - Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. - - File: TimerHighRes.hpp - Date: 2021-6-10 - Author: Reece -***/ -#pragma once - -namespace Aurora::Time -{ - class TimerHighRes - { - public: - TimerHighRes() - { - Start(); - } - - void Start() - { - start_ = HighResClockNS(); - } - - AuUInt64 End() - { - auto re = std::clamp(HighResClockNS() - start_, AuInt64(0), AuNumericLimits::max()); - if (re == AuNumericLimits::max()) return 0; // ez overflow in subtract. get out of here in 2-3 branches - return re; - } - - private: - AuUInt64 start_; - }; -} \ No newline at end of file diff --git a/Include/Aurora/Time/_Time.hpp b/Include/Aurora/Time/_Time.hpp new file mode 100644 index 00000000..2bd8c834 --- /dev/null +++ b/Include/Aurora/Time/_Time.hpp @@ -0,0 +1,31 @@ +/*** + Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: Time.hpp + Date: 2021-6-9 + Author: Reece +***/ +#pragma once + +#include +#include +#include + +#include "IClock.hpp" + +namespace Aurora::Time +{ + static AuString ConvertMSToTimescale(AuUInt32 ms) + { + return Locale::ConvertMSToTimescale(ms); + } + + static AuString ConvertNSToTimescale(AuUInt64 ns) + { + return Locale::ConvertNSToTimescale(ns); + } +} + +#include "Stopwatch.hpp" +#include "DebugBenchmark.hpp" +#include "ExtendedTimer.hpp" \ No newline at end of file diff --git a/Source/Time/AuClocks.cpp b/Source/Time/AuClocks.cpp new file mode 100644 index 00000000..c98b2ead --- /dev/null +++ b/Source/Time/AuClocks.cpp @@ -0,0 +1,68 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuClocks.cpp + Date: 2023-3-21 + Author: Reece +***/ +#include +#include "AuClocks.hpp" + +namespace Aurora::Time +{ +#define ADD_CLOCK(name, enum, jiffies, getNs, getMs) \ + struct name ## Clock_t : IClock \ + { \ + EClock GetType() override \ + { \ + return EClock::enum; \ + } \ + \ + AuUInt64 GetHertz() override \ + { \ + return jiffies(); \ + } \ + \ + AuUInt64 NowNS() override \ + { \ + return getNs(); \ + } \ + \ + AuUInt64 NowMS() override \ + { \ + return getMs(); \ + } \ + }; \ + \ + static name ## Clock_t gClock## name ## Instance; \ + \ + AUKN_SYM AuSPtr Get ## name ## Clock() \ + { \ + return AuUnsafeRaiiToShared(&gClock## name ## Instance); \ + } + +#define FILE_AND_USR_DIR_STEP (AuMSToNS(AuSToMS(1)) / 100ull) + + ADD_CLOCK(Steady, eSteady, SteadyClockJiffies, SteadyClockNS, SteadyClockMS); + ADD_CLOCK(Wall, eWall, FILE_AND_USR_DIR_STEP + AuUInt64, CurrentClockNS, CurrentClockMS); + ADD_CLOCK(ProcTime, eProcessTime, HighResClockJiffies, HighResClockNS, HighResClockMS); + +#undef FILE_AND_USR_DIR_STEP +#undef ADD_CLOCK + + AUKN_SYM AuSPtr GetClockFromEnum(EClock clock) + { + switch (clock) + { + case EClock::eWall: + return GetWallClock(); + case EClock::eProcessTime: + return GetProcessClock(); + case EClock::eSteady: + return GetSteadyClock(); + default: + SysPushErrorArg("Invalid clock"); + return {}; + } + } +} \ No newline at end of file diff --git a/Source/Time/AuClocks.hpp b/Source/Time/AuClocks.hpp new file mode 100644 index 00000000..f8956510 --- /dev/null +++ b/Source/Time/AuClocks.hpp @@ -0,0 +1,13 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuClocks.hpp + Date: 2023-3-21 + Author: Reece +***/ +#pragma once + +namespace Aurora::Time +{ + +} \ No newline at end of file