Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
f968d6a75f
3
.gitignore
vendored
3
.gitignore
vendored
@ -22,4 +22,5 @@ compile_flags.txt
|
||||
*.project
|
||||
*cmake
|
||||
.intellij
|
||||
.clion
|
||||
.clion
|
||||
Makefile
|
||||
|
@ -14,7 +14,7 @@
|
||||
{
|
||||
"if": "win32",
|
||||
"then": {
|
||||
"links": "Bcrypt.lib"
|
||||
"links": ["Bcrypt.lib", "UxTheme.lib"]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -215,13 +215,48 @@ namespace Aurora::Async
|
||||
AUKN_SYM AuSPtr<IWorkItem> NewWorkItem(const WorkerId_t &worker, const AuSPtr<IWorkItemHandler> &task, bool supportsBlocking = false);
|
||||
AUKN_SYM AuSPtr<IWorkItem> NewFence();
|
||||
|
||||
class IAsyncApp
|
||||
{
|
||||
public:
|
||||
// Main thread logic
|
||||
virtual void Start() = 0;
|
||||
virtual void Main() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool Exiting() = 0;
|
||||
virtual void SetConsoleCommandDispatcher(WorkerId_t id) = 0;
|
||||
|
||||
// Spawning
|
||||
virtual bool Spawn(WorkerId_t) = 0;
|
||||
virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) = 0;
|
||||
virtual AuBST<ThreadGroup_t, AuList<ThreadId_t>> GetThreads() = 0;
|
||||
virtual WorkerId_t GetCurrentThread() = 0;
|
||||
|
||||
// Synchronization
|
||||
// Note: syncing to yourself will nullify requireSignal to prevent deadlock
|
||||
virtual bool Sync(WorkerId_t group, AuUInt32 timeoutMs = 0, bool requireSignal = false) = 0;
|
||||
virtual void Signal(WorkerId_t group) = 0;
|
||||
virtual void SyncAllSafe() = 0;
|
||||
|
||||
// Features
|
||||
virtual void AddFeature(WorkerId_t id, AuSPtr<Threading::Threads::IThreadFeature> feature, bool async = false) = 0;
|
||||
|
||||
// Debug
|
||||
virtual void AssertInThreadGroup(ThreadGroup_t thread) = 0;
|
||||
virtual void AssertWorker(WorkerId_t id) = 0;
|
||||
|
||||
virtual bool Poll(bool block) = 0;
|
||||
|
||||
virtual bool ScheduleLoopSource(const AuSPtr<Loop::ILoopSource> &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer<AuSPtr<Loop::ILoopSource>, bool> &callback) = 0;
|
||||
};
|
||||
|
||||
|
||||
#pragma region EASE_OF_READING
|
||||
struct BasicWorkStdFunc : IWorkItemHandler
|
||||
{
|
||||
std::function<void()> callback;
|
||||
std::function<void()> shutdown;
|
||||
|
||||
BasicWorkStdFunc(std::function<void()> &&callback, std::function<void()> &&error) : callback(std::move(callback)), shutdown(std::move(shutdown))
|
||||
BasicWorkStdFunc(std::function<void()> &&callback, std::function<void()> &&error) : callback(std::move(callback)), shutdown(std::move(error))
|
||||
{}
|
||||
|
||||
BasicWorkStdFunc(std::function<void()> &&callback) : callback(std::move(callback))
|
||||
@ -340,7 +375,6 @@ namespace Aurora::Async
|
||||
|
||||
private:
|
||||
|
||||
|
||||
static constexpr bool IsCallbackPtr = std::is_pointer_v<Job_t> || AuIsBaseOfTemplate<std::shared_ptr, Job_t>::value;
|
||||
static constexpr bool IsTaskPtr = std::is_pointer_v<Task_t> || AuIsBaseOfTemplate<std::shared_ptr, Task_t>::value;
|
||||
|
||||
@ -483,8 +517,8 @@ namespace Aurora::Async
|
||||
}
|
||||
};
|
||||
|
||||
#define ASYNC_ERROR(exp) if constexpr (std::is_same_v<T, bool>) { SysPushErrorGen(exp); return {}; } else { throw std::exception(exp); }
|
||||
#define ASYNC_FINISH if constexpr (std::is_same_v<T, bool>) { return true; }
|
||||
#define ASYNC_ERROR(exp) { if constexpr (std::is_same_v<T, bool>) { SysPushErrorGen(exp); return {}; } else { throw std::string(exp); } }
|
||||
#define ASYNC_FINISH { if constexpr (std::is_same_v<T, bool>) { return true; } }
|
||||
|
||||
template<typename T = void, typename... Args, AU_TEMPLATE_ENABLE_WHEN(std::is_same_v<T, bool> || std::is_void<T>::value)>
|
||||
static std::function<T(Args&&...)> TranslateAsyncFunctionToDispatcherWithThread(WorkerId_t id, std::function<void(Args...)> func)
|
||||
@ -515,7 +549,7 @@ namespace Aurora::Async
|
||||
{
|
||||
auto work = AuMakeShared<BasicWorkCallback<AVoid, B>>();
|
||||
if (!work) ASYNC_ERROR("can't dispatch async call; out of memory");
|
||||
work.task.onProcess = [](const AVoid &) -> AuOptional<B>
|
||||
work.task.onProcess = [=](const AVoid &) -> AuOptional<B>
|
||||
{
|
||||
return func(in...);
|
||||
};
|
||||
@ -535,14 +569,7 @@ namespace Aurora::Async
|
||||
{
|
||||
return TranslateAsyncReturnableFunctionToDispatcherWithThread(GetAsyncApp()->GetCurrentThread(), func);
|
||||
}
|
||||
|
||||
#undef ASYNC_ERROR
|
||||
#undef ASYNC_FINISH
|
||||
|
||||
#endif
|
||||
|
||||
#pragma endregion EASE_OF_READING
|
||||
|
||||
|
||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>>
|
||||
static AuSPtr<Async::IWorkItem> DispatchBasicWorkCallback(const WorkerId_t &worker, const Task_t &task, const Job_t &job, bool enableWait = false)
|
||||
{
|
||||
@ -555,38 +582,10 @@ namespace Aurora::Async
|
||||
return Async::NewWorkItem(worker, AuMakeShared<Async::BasicWorkCallback<Info_t, Result_t>>(task, job, inputParameters), enableWait)->Dispatch();
|
||||
}
|
||||
|
||||
#undef ASYNC_ERROR
|
||||
#undef ASYNC_FINISH
|
||||
|
||||
class IAsyncApp
|
||||
{
|
||||
public:
|
||||
// Main thread logic
|
||||
virtual void Start() = 0;
|
||||
virtual void Main() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool Exiting() = 0;
|
||||
virtual void SetConsoleCommandDispatcher(WorkerId_t id) = 0;
|
||||
|
||||
// Spawning
|
||||
virtual bool Spawn(WorkerId_t) = 0;
|
||||
virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) = 0;
|
||||
virtual AuBST<ThreadGroup_t, AuList<ThreadId_t>> GetThreads() = 0;
|
||||
virtual WorkerId_t GetCurrentThread() = 0;
|
||||
|
||||
// Synchronization
|
||||
// Note: syncing to yourself will nullify requireSignal to prevent deadlock
|
||||
virtual bool Sync(WorkerId_t group, AuUInt32 timeoutMs = 0, bool requireSignal = false) = 0;
|
||||
virtual void Signal(WorkerId_t group) = 0;
|
||||
virtual void SyncAllSafe() = 0;
|
||||
|
||||
// Features
|
||||
virtual void AddFeature(WorkerId_t id, AuSPtr<Threading::Threads::IThreadFeature> feature, bool async = false) = 0;
|
||||
|
||||
// Debug
|
||||
virtual void AssertInThreadGroup(ThreadGroup_t thread) = 0;
|
||||
virtual void AssertWorker(WorkerId_t id) = 0;
|
||||
|
||||
virtual bool Poll(bool block) = 0;
|
||||
|
||||
virtual bool AddLoopSource(const AuSPtr<Loop::ILoopSource> &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer<AuSPtr<Loop::ILoopSource>, bool> &callback) = 0;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma endregion EASE_OF_READING
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ namespace Aurora::Data
|
||||
case DataType::kTypeStructInt32: return 4;
|
||||
case DataType::kTypeStructUInt64: return 8;
|
||||
case DataType::kTypeStructInt64: return 8;
|
||||
default: static_assert(false, "invalid datatype");
|
||||
default: return 0;//static_assert(false, "invalid datatype");
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,4 +146,4 @@ namespace Aurora::Data
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,10 @@ namespace Aurora::Debug
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
#pragma optimize("", off)
|
||||
#define _FREECOMPILER_OPTIMIZE_OFF
|
||||
#elif defined(AURORA_COMPILER_CLANG)
|
||||
#define _FREECOMPILER_OPTIMIZE_OFF __attribute__((optnone))
|
||||
#else
|
||||
#define _FREECOMPILER_OPTIMIZE_OFF [[gnu::optimize(0)]]
|
||||
#define _FREECOMPILER_OPTIMIZE_OFF __attribute__((optimize("0")))
|
||||
#endif
|
||||
|
||||
static AU_NOINLINE void ErrorMakeNested() _FREECOMPILER_OPTIMIZE_OFF
|
||||
@ -168,4 +170,4 @@ namespace Aurora::Debug
|
||||
#define SysPushErrorDisconnectedDbg(...)
|
||||
#define SysPushErrorUninitializedDbg(...)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -14,14 +14,15 @@ namespace Aurora::Memory
|
||||
/***
|
||||
* A bytebuffer object represents a linear, partially-linear resizable, buffer **or** a ring buffer.
|
||||
*
|
||||
* Use cases for a ring buffer include wrapping specific streams whereby your use cases may include
|
||||
* arbitrarily seeking around wrapped blocks of a more limited block stream, a network stream, or other api
|
||||
* Use cases for a ring buffer include wrapping streams for a use case in which the consumer may
|
||||
* expect arbitrary stream seeks of an otherwise limited consume-once stream
|
||||
*
|
||||
* IE;
|
||||
* -> peaking a header in a datagram, or tcp stream; where instead of freeing the datagram or saving
|
||||
* the buffered tcp stream, a ring buffer is used to prevent reallocation on each frame
|
||||
* -> peaking, or seeking back after, a compression read transaction. A compression api could be fed on-
|
||||
* demand or ad hoc, writing to its write head pointer, while never running out of space so long as
|
||||
* the decompressed ring read head continues moving
|
||||
* -> peaking a header in a datagram, or tcp stream; where instead of freeing the datagram or double
|
||||
* buffering the network stack when required, a ring buffer is used to prevent reallocation on each frame
|
||||
* -> peaking, or seeking back after, compression read. A compression api could be fed on-Sdemand or ad hoc,
|
||||
* writing to its write head pointer, while never running out of space so long as the decompressed ring
|
||||
* read head continues moving
|
||||
*
|
||||
* Small, linear, write/read-once [de]serialization use cases may elect to allocate a buffer and
|
||||
* follow the linear fast paths; perhaps even enabling flagExpandable for hopefully-smarter-than-stdvec-scaling
|
||||
@ -159,7 +160,7 @@ namespace Aurora::Memory
|
||||
AUKN_SYM AuOptional<AuUInt8 *> WriterTryGetWriteHeadFor(AuUInt32 nBytes);
|
||||
|
||||
// Template implementation
|
||||
// TODO: remove to .inl
|
||||
// TODO: move to .inl
|
||||
|
||||
template<typename T>
|
||||
inline bool Read(T &out)
|
||||
|
@ -72,13 +72,13 @@ namespace Aurora::Memory
|
||||
template<typename T>
|
||||
T FRealloc(T in, Types::size_t length)
|
||||
{
|
||||
return reinterpret_cast<T>(_SRealloc(reinterpret_cast<void *>(in), length));
|
||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(in), length));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T FRealloc(T in, Types::size_t length, Types::size_t alloc)
|
||||
{
|
||||
return reinterpret_cast<T>(_SRealloc(reinterpret_cast<void *>(in), length), alloc);
|
||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(in), length), alloc);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -136,4 +136,4 @@ namespace Aurora::Memory
|
||||
@return a heap backed by allocated memory
|
||||
*/
|
||||
AUKN_SHARED_API(AllocHeap, Heap, AuUInt size);
|
||||
}
|
||||
}
|
||||
|
@ -38,14 +38,14 @@ namespace Aurora::Memory
|
||||
template<typename T>
|
||||
T ZAlloc(Types::size_t length)
|
||||
{
|
||||
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
static_assert(!std::is_class<typename std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
return reinterpret_cast<T>(_ZAlloc(length));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ZAlloc(Types::size_t length, Types::size_t align)
|
||||
{
|
||||
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
static_assert(!std::is_class<typename std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
return reinterpret_cast<T>(_ZAlloc(length, align));
|
||||
}
|
||||
|
||||
@ -53,20 +53,20 @@ namespace Aurora::Memory
|
||||
T *NewArray(Types::size_t count)
|
||||
{
|
||||
static_assert(!std::is_class<T>::value, "Do not use heap/kmem apis with classes");
|
||||
return FAlloc<T *>(count * sizeof(T));
|
||||
return reinterpret_cast<T *>(_FAlloc(count * sizeof(T)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *NewArray(Types::size_t count, Types::size_t align)
|
||||
{
|
||||
static_assert(!std::is_class<T>::value, "Do not use heap/kmem apis with classes");
|
||||
return FAlloc<T *>(count * sizeof(T), align);
|
||||
return reinterpret_cast<T *>(_FAlloc(count * sizeof(T)), align);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
AuSPtr<T> AllocateFastArray(Types::size_t length, Types::size_t align = sizeof(T))
|
||||
{
|
||||
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
static_assert(!std::is_class<typename std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
return AuSPtr<T>(reinterpret_cast<T *>(_FAlloc(length)), [](T *ptr)
|
||||
{
|
||||
_Free(ptr);
|
||||
@ -102,14 +102,14 @@ namespace Aurora::Memory
|
||||
template<typename T>
|
||||
T FAlloc(Types::size_t length)
|
||||
{
|
||||
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
static_assert(!std::is_class<typename std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
return reinterpret_cast<T>(_FAlloc(length));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T FAlloc(Types::size_t length, Types::size_t align)
|
||||
{
|
||||
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
static_assert(!std::is_class<typename std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
|
||||
return reinterpret_cast<T>(_FAlloc(length, align));
|
||||
}
|
||||
|
||||
@ -146,4 +146,4 @@ namespace Aurora::Memory
|
||||
}
|
||||
|
||||
#include "Array.hpp"
|
||||
#include "ByteBuffer.hpp"
|
||||
#include "ByteBuffer.hpp"
|
||||
|
@ -39,7 +39,7 @@ namespace Aurora::Memory
|
||||
MemoryView(T &list)
|
||||
{
|
||||
this->ptr = list.data();
|
||||
this->length = list.size() * sizeof(T::value_type);
|
||||
this->length = list.size() * sizeof(typename T::value_type);
|
||||
}
|
||||
|
||||
MemoryView(const AuString &str)
|
||||
@ -173,4 +173,4 @@ namespace Aurora::Memory
|
||||
|
||||
using MemoryViewStreamRead = MemoryViewStream<true>;
|
||||
using MemoryViewStreamWrite = MemoryViewStream<false>;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <intrin.h>
|
||||
|
||||
#include "../AuroraTypedefs.hpp"
|
||||
#include "../AuroraUtils.hpp"
|
||||
|
@ -29,6 +29,8 @@ namespace Aurora::Time
|
||||
*/
|
||||
AUKN_SYM time_t MSToCTime(AuInt64 time);
|
||||
|
||||
AUKN_SYM AuInt64 CTimeToMS(time_t time);
|
||||
|
||||
/**
|
||||
Converts milliseconds from the Aurora epoch to a civil timestamp structure
|
||||
similar to or of std::tm
|
||||
@ -111,4 +113,4 @@ namespace Aurora::Time
|
||||
Retrieves the freqency of jiffies per second
|
||||
*/
|
||||
AUKN_SYM AuUInt64 ClockJiffies();
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ name ## Shared_t name ## Shared(T... args) \
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
#define AU_NORETURN __declspec(noreturn)
|
||||
#elif (defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC))
|
||||
#define AU_ALLOC __attribute__((noreturn))
|
||||
#define AU_NORETURN __attribute__((noreturn))
|
||||
#elif defined(AU_LANG_CPP)
|
||||
#define AU_NORETURN [[noreturn]]
|
||||
#else
|
||||
|
@ -175,8 +175,13 @@ static const AuThreadId_t kThreadIdSpecialMask = AuThreadId_t(1) << AuThreadId_t
|
||||
struct AuFVec
|
||||
{
|
||||
float elements[N];
|
||||
|
||||
float &operator [](int idx) const
|
||||
|
||||
float operator [](int idx) const
|
||||
{
|
||||
return elements[N];
|
||||
}
|
||||
|
||||
float &operator [](int idx)
|
||||
{
|
||||
return elements[N];
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ static inline void __declspec(noreturn) SysPanic(T... args);
|
||||
template<typename Z, typename T>
|
||||
static void inline SafeDelete(T *in)
|
||||
{
|
||||
static_assert(std::is_base_of<T, std::remove_pointer<Z>::type>::value, "Couldn't not safe delete from type T because it is not derived from Z");
|
||||
static_assert(std::is_base_of<T, typename std::remove_pointer<Z>::type>::value, "Couldn't not safe delete from type T because it is not derived from Z");
|
||||
auto cast = dynamic_cast<Z>(in);
|
||||
if (cast == nullptr)
|
||||
{
|
||||
@ -87,7 +87,7 @@ static void inline SafeDelete(T *in)
|
||||
template<typename Z, typename T>
|
||||
static void inline SafeDelete(T *in)
|
||||
{
|
||||
static_assert(std::is_base_of<T, std::remove_pointer<Z>::type>::value, "Couldn't not safe delete from type T because it is not derived from Z");
|
||||
static_assert(std::is_base_of<T, typename std::remove_pointer<Z>::type>::value, "Couldn't not safe delete from type T because it is not derived from Z");
|
||||
delete static_cast<Z>(in);
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ namespace Aurora::Async
|
||||
return ranAtLeastOne;
|
||||
}
|
||||
|
||||
bool AsyncApp::AddLoopSource(const AuSPtr<Loop::ILoopSource> &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer<AuSPtr<Loop::ILoopSource>, bool> &callback)
|
||||
bool AsyncApp::ScheduleLoopSource(const AuSPtr<Loop::ILoopSource> &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer<AuSPtr<Loop::ILoopSource>, bool> &callback)
|
||||
{
|
||||
auto thread = this->GetThreadHandle(workerId);
|
||||
if (!thread)
|
||||
|
@ -62,7 +62,7 @@ namespace Aurora::Async
|
||||
bool CtxYield();
|
||||
int CfxPollPush();
|
||||
void CtxPollReturn(const AuSPtr<ThreadState> &state, int status, bool hitTask);
|
||||
bool AddLoopSource(const AuSPtr<Loop::ILoopSource> &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer<AuSPtr<Loop::ILoopSource>, bool> &callback) override;
|
||||
bool ScheduleLoopSource(const AuSPtr<Loop::ILoopSource> &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer<AuSPtr<Loop::ILoopSource>, bool> &callback) override;
|
||||
|
||||
private:
|
||||
AuSPtr<ThreadState> GetThreadHandle(WorkerId_t id);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace Aurora::Console
|
||||
{
|
||||
static std::array<std::string, static_cast<size_t>(EAnsiColor::eCount)> AnsiCheats
|
||||
static std::array<std::string, static_cast<size_t>(EAnsiColor::eCount)> kAnsiCheats
|
||||
{
|
||||
"\033[0;31m",
|
||||
"\033[1;31m",
|
||||
@ -51,7 +51,7 @@ namespace Aurora::Console
|
||||
|
||||
AuString ConsoleMessage::ToConsole() const
|
||||
{
|
||||
return fmt::format("{}[{}] {:<7} | {}{}", AnsiCheats[static_cast<size_t>(color)], StringifyTime(), GetWrappedTag(), line, AnsiCheats[static_cast<size_t>(EAnsiColor::eReset)]);
|
||||
return fmt::format("{}[{}] {:<7} | {}{}", kAnsiCheats[static_cast<size_t>(color)], StringifyTime(), GetWrappedTag(), line, kAnsiCheats[static_cast<size_t>(EAnsiColor::eReset)]);
|
||||
}
|
||||
|
||||
AuString ConsoleMessage::ToSimplified() const
|
||||
|
@ -112,7 +112,7 @@ namespace Aurora::Console::ConsoleStd
|
||||
{
|
||||
AuString slow;
|
||||
slow.resize(writeLine.size() * 4);
|
||||
auto len = Locale::Encoding::EncodeUTF8(writeLine, reinterpret_cast<AuUInt8 *>(slow.data()), slow.size(), Locale::ECodePage::eSysUnk);
|
||||
auto len = Locale::Encoding::EncodeUTF8(writeLine, Aurora::Memory::MemoryViewWrite {slow.data(), slow.size()}, Locale::ECodePage::eSysUnk);
|
||||
if (len.first != 0)
|
||||
{
|
||||
WriteStdOut(slow.data(), len.second);
|
||||
@ -534,4 +534,4 @@ namespace Aurora::Console::ConsoleStd
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "ECC.hpp"
|
||||
#include "ECCx25519.hpp"
|
||||
//#include "ECCx25519.hpp"
|
||||
|
||||
namespace Aurora::Crypto::ECC
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ namespace Aurora::Debug
|
||||
|
||||
#if defined(DEBUG)
|
||||
IMAGEHLP_LINE64 line;
|
||||
DWORD disp;
|
||||
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
|
||||
if (SymGetLineFromAddr64(process, stack.AddrPC.Offset, &disp, &line))
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "Debug.hpp"
|
||||
#include "Panic.hpp"
|
||||
#include <intrin.h>
|
||||
//#include <intrin.h>
|
||||
#include <Source/Console/ConsoleFIO/ConsoleFIO.hpp>
|
||||
|
||||
namespace Aurora::Debug
|
||||
@ -26,7 +26,7 @@ namespace Aurora::Debug
|
||||
#elif defined(DEBUG)
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
__debugbreak();
|
||||
#elif defined(__has_builtin) && __has_builtin(__builtin_debugtrap))
|
||||
#elif (defined(__has_builtin) && __has_builtin(__builtin_debugtrap))
|
||||
__builtin_debugtrap();
|
||||
#elif defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG)
|
||||
// GCC is a terrible compiler, msvc is annoying at best, and LLVM + cpp frontend seems great, whats new?
|
||||
@ -92,4 +92,4 @@ namespace Aurora::Debug
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,10 @@
|
||||
#include <sys/sysinfo.h>
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG) || defined(AURORA_IS_POSIX_DERIVED)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
namespace Aurora::HWInfo
|
||||
{
|
||||
static CpuInfo gCpuInfo;
|
||||
@ -459,7 +463,7 @@ namespace Aurora::HWInfo
|
||||
|
||||
gCpuInfo.socket = 1;
|
||||
gCpuInfo.cores = 1;
|
||||
gCpuInfo.threads = get_nprocs(void);
|
||||
gCpuInfo.threads = get_nprocs();
|
||||
|
||||
#elif defined(AURORA_IS_POSIX_DERIVED)
|
||||
|
||||
@ -476,4 +480,4 @@ namespace Aurora::HWInfo
|
||||
SetCpuId();
|
||||
SetCpuTopology();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
@ -124,4 +125,4 @@ namespace Aurora::HWInfo
|
||||
{
|
||||
gMemStartup = GetMemStatSystem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,13 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include <sys/sendfile.h>
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO::FS
|
||||
{
|
||||
bool _MkDir(const AuString &str)
|
||||
bool _MkDir(const AuString &path)
|
||||
{
|
||||
return mkdir(path.c_str(), 0760) == 0;
|
||||
}
|
||||
@ -34,13 +38,27 @@ namespace Aurora::IO::FS
|
||||
return IterateDirEntriesSTL(string, false, dirs);
|
||||
}
|
||||
|
||||
AUKN_SYM bool WriteFile(const AuString &path, const void *data, size_t length)
|
||||
AUKN_SYM bool WriteFile(const AuString &path, const void *data, AuUInt length)
|
||||
{
|
||||
auto file = OpenWriteUnique(path);
|
||||
SysCheckReturn(file, false);
|
||||
return file->Read(data, length) == length;
|
||||
}
|
||||
|
||||
|
||||
AuUInt written = length;
|
||||
if (!file->Write(Memory::MemoryViewStreamRead(data, written)))
|
||||
{
|
||||
SysPushErrorMem();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (written != length)
|
||||
{
|
||||
SysPushErrorIO();
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AUKN_SYM bool ReadFile(const AuString &path, AuList<uint8_t> &buffer)
|
||||
{
|
||||
auto file = OpenReadUnique(path);
|
||||
@ -53,7 +71,20 @@ namespace Aurora::IO::FS
|
||||
return false;
|
||||
}
|
||||
|
||||
return file->Read(buffer.data(), buffer.size()) == buffer.size();
|
||||
AuUInt read;
|
||||
if (!file->Read(Memory::MemoryViewStreamWrite {buffer, read}))
|
||||
{
|
||||
SysPushErrorIO();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (read != buffer.size())
|
||||
{
|
||||
SysPushErrorIO();
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool UnixExists(const AuString &path, bool dir)
|
||||
@ -85,7 +116,7 @@ namespace Aurora::IO::FS
|
||||
|
||||
AUKN_SYM bool Remove(const AuString &path)
|
||||
{
|
||||
return remove(RetPathHelper(path).c_str()) != -1;
|
||||
return remove(NormalizePathRet(path).c_str()) != -1;
|
||||
}
|
||||
|
||||
AUKN_SYM bool Relink(const AuString &src, const AuString &dest)
|
||||
@ -110,7 +141,7 @@ namespace Aurora::IO::FS
|
||||
struct stat fileinfo = { 0 };
|
||||
if (fstat(input, &fileinfo) != 0)
|
||||
{
|
||||
close(input)
|
||||
close(input);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -178,7 +209,7 @@ namespace Aurora::IO::FS
|
||||
auto path = NormalizePathRet(pathRel);
|
||||
|
||||
struct stat s;
|
||||
auto err = stat(path.c_str(), &s);
|
||||
auto err = ::stat(path.c_str(), &s);
|
||||
|
||||
if (err == -1)
|
||||
{
|
||||
@ -202,9 +233,9 @@ namespace Aurora::IO::FS
|
||||
|
||||
stat.size = s.st_size;
|
||||
|
||||
stat.created = ConvertUnixTimespecToMs(s.st_ctime);
|
||||
stat.modified = ConvertUnixTimespecToMs(s.st_mtime);
|
||||
stat.accessed = ConvertUnixTimespecToMs(s.st_atime);
|
||||
stat.created = Time::CTimeToMS(s.st_ctime);
|
||||
stat.modified = Time::CTimeToMS(s.st_mtime);
|
||||
stat.accessed = Time::CTimeToMS(s.st_atime);
|
||||
|
||||
err = lstat(path.c_str(), &s);
|
||||
if (err != -1)
|
||||
@ -215,4 +246,4 @@ namespace Aurora::IO::FS
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -40,9 +40,9 @@ namespace Aurora::IO::FS
|
||||
try
|
||||
{
|
||||
#if defined(NO_STD_FS)
|
||||
stream_.open(RetPathHelper(str), std::ios_base::binary)
|
||||
stream_.open(NormalizePathRet(str), std::ios_base::binary)
|
||||
#else
|
||||
stream_.open(std::filesystem::u8path(RetPathHelper(str)), std::ios_base::binary);
|
||||
stream_.open(std::filesystem::u8path(NormalizePathRet(str)), std::ios_base::binary);
|
||||
#endif
|
||||
}
|
||||
catch (...)
|
||||
@ -236,4 +236,4 @@ namespace Aurora::IO::FS
|
||||
SafeDelete<StdWriteFS *>(that);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -30,7 +30,7 @@ namespace Aurora::IO::FS
|
||||
auto ret = lseek(fd, offset, whence);
|
||||
#else
|
||||
#error accient 32-bit posix operating systems require 64-bit file awareness
|
||||
#end
|
||||
#endif
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -147,7 +147,7 @@ namespace Aurora::IO::FS
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PosixSetOffset(handle_);
|
||||
return PosixSetOffset(handle_, offset);
|
||||
}
|
||||
|
||||
AuUInt64 PosixFileStream::GetLength()
|
||||
@ -179,7 +179,7 @@ namespace Aurora::IO::FS
|
||||
|
||||
if (!PosixRead(handle_, &reinterpret_cast<char *>(parameters.ptr)[offset], blockSize, &read))
|
||||
{
|
||||
SysPushErrorNested("File Error: {}", path);
|
||||
SysPushErrorNested("File Error: {}", path_);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -219,14 +219,14 @@ namespace Aurora::IO::FS
|
||||
|
||||
if (!PosixWrite(handle_, &reinterpret_cast<const char *>(parameters.ptr)[offset], blockSize, &written))
|
||||
{
|
||||
SysPushErrorNested("File Error: {}", path);
|
||||
SysPushErrorNested("File Error: {}", path_);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (written != blockSize)
|
||||
{
|
||||
SysPushErrorIO();
|
||||
SysPushErrorNested("File Error: {}", path);
|
||||
SysPushErrorNested("File Error: {}", path_);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -307,4 +307,4 @@ namespace Aurora::IO::FS
|
||||
SafeDelete<PosixFileStream *>(that);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -11,18 +11,18 @@
|
||||
|
||||
namespace Aurora::IO::FS
|
||||
{
|
||||
class PosixStream : public IFileStream
|
||||
class PosixFileStream : public IFileStream
|
||||
{
|
||||
public:
|
||||
~PosixStream();
|
||||
~PosixFileStream();
|
||||
|
||||
void Init(int handle, const AuString &path);
|
||||
|
||||
AuUInt64 GetOffset() override;
|
||||
bool SetOffset(AuUInt64 offset) override;
|
||||
AuUInt64 GetLength() override;
|
||||
AuUInt64 Read(void *in, AuUInt64 length) override;
|
||||
AuUInt64 Write(const void *out, AuUInt64 length) override;
|
||||
bool Read(const Memory::MemoryViewStreamWrite ¶meters) override;
|
||||
bool Write(const Memory::MemoryViewStreamRead & parameters) override;
|
||||
void Close() override;
|
||||
void Flush() override;
|
||||
|
||||
@ -32,4 +32,4 @@ namespace Aurora::IO::FS
|
||||
AuString path_;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -57,12 +57,20 @@ namespace Aurora::Locale::Encoding
|
||||
|
||||
AuStreamReadWrittenPair_t Win32ConvertFromCPToUTF8(AuUInt32 cp, const void *in, AuUInt length, void *utf8, AuUInt32 utf8Len)
|
||||
{
|
||||
#if !defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
|
||||
return {};
|
||||
#else
|
||||
return Win32ConvertCpAToCPB(cp, CP_UTF8, in, length, utf8, utf8Len);
|
||||
#endif
|
||||
}
|
||||
|
||||
AuStreamReadWrittenPair_t Win32ConvertFromUTF8ToCp(AuUInt32 cp, const void *utf8, AuUInt utf8Length, void *cpBlob, AuUInt32 cpLen)
|
||||
{
|
||||
#if !defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
|
||||
return {};
|
||||
#else
|
||||
return Win32ConvertCpAToCPB(CP_UTF8, cp, utf8, utf8Length, cpBlob, cpLen);
|
||||
#endif
|
||||
}
|
||||
|
||||
AuStreamReadWrittenPair_t Win32ConvertFromUTF16ToUTF8(const void *in, AuUInt32 inLength, void *utf8, AuUInt32 utf8Len)
|
||||
@ -144,6 +152,7 @@ namespace Aurora::Locale::Encoding
|
||||
{
|
||||
AuStreamReadWrittenPair_t ret {};
|
||||
|
||||
#if defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
|
||||
switch (page)
|
||||
{
|
||||
default:
|
||||
@ -174,6 +183,7 @@ namespace Aurora::Locale::Encoding
|
||||
ret = Win32ConvertFromUTF16ToUTF8(in, length, utf8, utf8Max);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -182,6 +192,7 @@ namespace Aurora::Locale::Encoding
|
||||
{
|
||||
AuStreamReadWrittenPair_t ret {};
|
||||
|
||||
#if defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
|
||||
switch (page)
|
||||
{
|
||||
default:
|
||||
@ -212,6 +223,7 @@ namespace Aurora::Locale::Encoding
|
||||
ret = Win32ConvertFromUTF16ToUTF8(in, length, utf8, utf8Max);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -219,7 +231,8 @@ namespace Aurora::Locale::Encoding
|
||||
AuStreamReadWrittenPair_t Win32UTF8ToCp(ECodePage page, const void *utf8, AuUInt32 utf8Length, void *cp, AuUInt32 cpLen)
|
||||
{
|
||||
AuStreamReadWrittenPair_t ret {};
|
||||
|
||||
|
||||
#if defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
|
||||
switch (page)
|
||||
{
|
||||
default:
|
||||
@ -249,6 +262,7 @@ namespace Aurora::Locale::Encoding
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
Date: 2021-6-11
|
||||
Author: Reece
|
||||
***/
|
||||
#define I_REALLY_NEED_WIDECHAR_PUBAPI
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "Locale.hpp"
|
||||
|
||||
@ -222,7 +223,7 @@ namespace Aurora::Locale
|
||||
auto parseTable = ParseLocaleString(locale);
|
||||
|
||||
AuString *lc;
|
||||
if ((TryFind(parseTable, '!', lc)) && (lc->size()))
|
||||
if ((AuTryFind(parseTable, '!', lc)) && (lc->size()))
|
||||
{
|
||||
gLanguageCode = *lc;
|
||||
}
|
||||
@ -234,7 +235,7 @@ namespace Aurora::Locale
|
||||
}
|
||||
|
||||
AuString *cc;
|
||||
if ((TryFind(parseTable, '_', cc)) && (cc->size()))
|
||||
if ((AuTryFind(parseTable, '_', cc)) && (cc->size()))
|
||||
{
|
||||
gCountryCode = *cc;
|
||||
}
|
||||
@ -244,7 +245,7 @@ namespace Aurora::Locale
|
||||
}
|
||||
|
||||
AuString *cs;
|
||||
if ((TryFind(parseTable, '.', cs)) && (cs->size()))
|
||||
if ((AuTryFind(parseTable, '.', cs)) && (cs->size()))
|
||||
{
|
||||
gCodeset = *cs;
|
||||
}
|
||||
@ -361,4 +362,4 @@ namespace Aurora::Locale
|
||||
gLockLocale = true;
|
||||
return LocalizationInfo(gLanguageCode, gCountryCode, gCodeset, gInternalCodePage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#define I_REALLY_NEED_WIDECHAR_PUBAPI
|
||||
|
||||
#if defined (VENDOR_GENERIC_MICROSOFT) || defined(VENDOR_CONSOLE_MICROSOFT)
|
||||
// https://docs.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/localization/supported_nls_apis
|
||||
#define AU_HAS_MSFT_NATIONALLANGSUPPORT
|
||||
@ -54,4 +56,4 @@ namespace Aurora::Locale
|
||||
/// bool DecodeStringToUTF8(AuUInt8 *readWriteHead, int length, AuString &decoded, ECodePage guess = ECodePage::eNotRead);
|
||||
}
|
||||
|
||||
#include "Encoding/Encoding.hpp"
|
||||
#include "Encoding/Encoding.hpp"
|
||||
|
20
Source/Loop/ILoopSourceEx.hpp
Normal file
20
Source/Loop/ILoopSourceEx.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ILoopSourceEx.hpp
|
||||
Date: 2021-10-3
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class ILoopSourceEx : public ILoopSource
|
||||
{
|
||||
public:
|
||||
virtual void OnPresleep() = 0;
|
||||
virtual bool OnTrigger(AuUInt handle, bool atomicSignal) = 0;
|
||||
virtual void OnFinishSleep() = 0;
|
||||
virtual AuList<AuUInt> GetHandles() = 0;
|
||||
};
|
||||
}
|
44
Source/Loop/LSAsync.cpp
Normal file
44
Source/Loop/LSAsync.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: LSAsync.cpp
|
||||
Date: 2021-10-3
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "LSAsync.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class AsyncWaiter : public ILoopSource
|
||||
{
|
||||
public:
|
||||
AsyncWaiter()
|
||||
{}
|
||||
|
||||
bool IsSignaled() override;
|
||||
ELoopSource GetType() override;
|
||||
};
|
||||
|
||||
bool AsyncWaiter::IsSignaled()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
ELoopSource AsyncWaiter::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceMutex;
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ILoopSource> NewLSAsync()
|
||||
{
|
||||
AuSPtr<ILoopSource> ret;
|
||||
|
||||
if (!(ret = AuMakeShared<AsyncWaiter>()))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
13
Source/Loop/LSAsync.hpp
Normal file
13
Source/Loop/LSAsync.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: LSAsync.hpp
|
||||
Date: 2021-10-3
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
}
|
@ -10,5 +10,13 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
AUKN_SYM AuSPtr<IConditionVar> NewLSCondVar(const AuSPtr<Aurora::Threading::IWaitable> &primitive)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<IConditionVar> NewLSCondVar(const AuSPtr<ILSMutex> &source)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
@ -10,5 +10,42 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
bool Event::Set()
|
||||
{
|
||||
return SetEvent(reinterpret_cast<HANDLE>(this->handle));
|
||||
}
|
||||
|
||||
bool Event::Reset()
|
||||
{
|
||||
return ResetEvent(reinterpret_cast<HANDLE>(this->handle));
|
||||
}
|
||||
|
||||
bool Event::IsSignaled()
|
||||
{
|
||||
return LSHandle::IsSignaled();
|
||||
}
|
||||
|
||||
ELoopSource Event::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceEvent;
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ILSEvent> NewLSEvent(bool triggerd, bool atomicRelease, bool permitMultipleTriggers)
|
||||
{
|
||||
AuSPtr<ILSEvent> ret;
|
||||
|
||||
auto mutex = CreateEvent(NULL, !atomicRelease, triggerd, NULL);
|
||||
if (mutex == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SysPushErrorGen("Out of OS resources?");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!(ret = AuMakeShared<Event>(mutex)))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -6,8 +6,20 @@
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
#include "LSHandle.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
class Event : public ILSEvent, public LSHandle
|
||||
{
|
||||
public:
|
||||
Event(HANDLE handle) : LSHandle(reinterpret_cast<AuUInt>(handle))
|
||||
{}
|
||||
|
||||
bool Set() override;
|
||||
bool Reset() override;
|
||||
|
||||
bool ILSEvent::IsSignaled() override;
|
||||
ELoopSource ILSEvent::GetType() override;
|
||||
};
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include "LSEvent.NT.hpp"
|
||||
// eventfd always atomically resets
|
||||
|
@ -10,5 +10,32 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
LSHandle::LSHandle(AuUInt handle) : handle(handle), reference({handle})
|
||||
{}
|
||||
|
||||
bool LSHandle::OnTrigger(AuUInt handle, bool atomicSignal)
|
||||
{
|
||||
return atomicSignal;
|
||||
}
|
||||
|
||||
AuList<AuUInt> LSHandle::GetHandles()
|
||||
{
|
||||
return reference;
|
||||
}
|
||||
|
||||
ELoopSource LSHandle::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceHandle;
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ILoopSource> NewLSOSHandle(AuUInt handle)
|
||||
{
|
||||
auto h = reinterpret_cast<HANDLE>(handle);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return AuMakeShared<LSHandle>(handle);
|
||||
}
|
||||
}
|
@ -7,7 +7,23 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
class LSHandle : public WaitSingleGeneric
|
||||
{
|
||||
public:
|
||||
LSHandle(AuUInt handle);
|
||||
|
||||
bool OnTrigger(AuUInt handle, bool atomicSignal) override;
|
||||
AuList<AuUInt> GetHandles() override;
|
||||
ELoopSource GetType() override;
|
||||
|
||||
protected:
|
||||
AuUInt handle;
|
||||
|
||||
private:
|
||||
AuList<AuUInt> reference;
|
||||
};
|
||||
}
|
@ -10,5 +10,37 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
bool Mutex::Unlock()
|
||||
{
|
||||
return ReleaseMutex(reinterpret_cast<HANDLE>(handle));
|
||||
}
|
||||
|
||||
bool Mutex::IsSignaled()
|
||||
{
|
||||
return LSHandle::IsSignaled();
|
||||
}
|
||||
|
||||
ELoopSource Mutex::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceMutex;
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ILSMutex> NewLSMutex()
|
||||
{
|
||||
AuSPtr<ILSMutex> ret;
|
||||
|
||||
auto mutex = CreateMutex(NULL, false, NULL);
|
||||
if (mutex == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SysPushErrorGen("Out of OS resources?");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!(ret = AuMakeShared<Mutex>(mutex)))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -6,8 +6,19 @@
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
#include "LSHandle.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
class Mutex : public ILSMutex, public LSHandle
|
||||
{
|
||||
public:
|
||||
Mutex(HANDLE handle) : LSHandle(reinterpret_cast<AuUInt>(handle))
|
||||
{}
|
||||
|
||||
bool Unlock() override;
|
||||
|
||||
bool ILSMutex::IsSignaled() override;
|
||||
ELoopSource ILSMutex::GetType() override;
|
||||
};
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include "LSMutex.NT.hpp"
|
||||
#elif defined(AURORA_IS_LINUX_DERIVED)
|
||||
|
@ -9,5 +9,5 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
|
||||
}
|
@ -10,5 +10,38 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
bool Semaphore::AddOne()
|
||||
{
|
||||
LONG atomicOld;
|
||||
return ReleaseSemaphore(reinterpret_cast<HANDLE>(handle), 1, &atomicOld);
|
||||
}
|
||||
|
||||
bool Semaphore::IsSignaled()
|
||||
{
|
||||
return LSHandle::IsSignaled();
|
||||
}
|
||||
|
||||
ELoopSource Semaphore::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceSemaphore;
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ILSSemaphore> NewLSSemaphore(AuUInt32 initialCount)
|
||||
{
|
||||
AuSPtr<Semaphore> ret;
|
||||
|
||||
auto mutex = CreateSemaphoreA(NULL, initialCount, std::numeric_limits<LONG>::max(), NULL);
|
||||
if (mutex == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SysPushErrorGen("Out of OS resources?");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!(ret = AuMakeShared<Semaphore>(mutex)))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -6,8 +6,19 @@
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
#include "LSHandle.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class Semaphore : public ILSSemaphore, public LSHandle
|
||||
{
|
||||
public:
|
||||
Semaphore(HANDLE handle) : LSHandle(reinterpret_cast<AuUInt>(handle))
|
||||
{}
|
||||
|
||||
bool AddOne() override;
|
||||
|
||||
bool ILSSemaphore::IsSignaled() override;
|
||||
ELoopSource ILSSemaphore::GetType() override;
|
||||
};
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include "LSSemaphore.NT.hpp"
|
||||
|
@ -10,5 +10,5 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
#include "LSHandle.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
@ -1,11 +1,19 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: LSTimer.hpp
|
||||
Date: 2021-10-2
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include "LSTimer.NT.hpp"
|
||||
#elif defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include "LSTimer.Linux.hpp"
|
||||
#else
|
||||
#define IMPL_LS_TIMER_GEN
|
||||
#include "LSTimer.Generic.hpp"
|
||||
#define IMPL_LS_TIMER_GEN
|
||||
#include "LSTimer.Generic.hpp"
|
||||
#endif
|
@ -9,5 +9,5 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
|
||||
}
|
14
Source/Loop/Loop.BSD.cpp
Normal file
14
Source/Loop/Loop.BSD.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: Loop.BSD.cpp
|
||||
Date: 2021-10-1
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "Loop.BSD.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
// TODO: kevent + pipe abuse
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: GenericWaitable.hpp
|
||||
Date: 2021-10-2
|
||||
File: Loop.BSD.hpp
|
||||
Date: 2021-10-1
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
@ -10,5 +10,8 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
AUKN_SYM AuList<AuSPtr<ILoopSource>> WaitMultipleObjects(const AuList<AuSPtr<ILoopSource>> &objects, AuUInt32 timeout)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
@ -10,11 +10,19 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
#if !defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
AUKN_SYM AuSPtr<ITimer> NewLSTimer(AuUInt64 absTimeMs);
|
||||
|
||||
#if !defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
AUKN_SYM AuSPtr<ILoopSource> NewLSWin32Source()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_IS_XNU_DERIVED)
|
||||
|
||||
AUKN_SYM AuSPtr<ILoopSource> NewLSAppleSource()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,15 +1,18 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: GenericWaitable.cpp
|
||||
File: WaitSingle.Generic.cpp
|
||||
Date: 2021-10-2
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "GenericWaitable.hpp"
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
#if defined(IMPL_WAIT_SINGLE_GEN)
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
20
Source/Loop/WaitSingle.Generic.hpp
Normal file
20
Source/Loop/WaitSingle.Generic.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.Generic.hpp
|
||||
Date: 2021-10-2
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class WaitSingleGeneric : public WaitSingleBase
|
||||
{
|
||||
public:
|
||||
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles, AuUInt &one) override;
|
||||
virtual void OnPresleep() override;
|
||||
virtual void OnFinishSleep() override;
|
||||
virtual ELoopSource GetType() override;
|
||||
};
|
||||
}
|
14
Source/Loop/WaitSingle.Linux.cpp
Normal file
14
Source/Loop/WaitSingle.Linux.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: LSTimer.Linux.cpp
|
||||
Date: 2021-10-1
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "LSTimer.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
}
|
13
Source/Loop/WaitSingle.Linux.hpp
Normal file
13
Source/Loop/WaitSingle.Linux.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.Linux.hpp
|
||||
Date: 2021-10-1
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
}
|
51
Source/Loop/WaitSingle.NT.cpp
Normal file
51
Source/Loop/WaitSingle.NT.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.NT.cpp
|
||||
Date: 2021-10-1
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "WaitSingle.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
|
||||
bool WaitSingleGeneric::WaitForAtleastOne(const AuList<AuUInt> &handles, AuUInt &one)
|
||||
{
|
||||
if (handles.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (handles.size() == 1)
|
||||
{
|
||||
return WaitForSingleObject(reinterpret_cast<HANDLE>(handles.at(0)), 0) == WAIT_OBJECT_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
AuList<HANDLE> ntHandles;
|
||||
ntHandles.reserve(handles.size());
|
||||
for (const auto &handle : handles)
|
||||
{
|
||||
ntHandles.push_back(reinterpret_cast<HANDLE>(handle));
|
||||
}
|
||||
return WaitForMultipleObjects(ntHandles.size(), ntHandles.data(), false, 0) >= WAIT_OBJECT_0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitSingleGeneric::OnPresleep()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WaitSingleGeneric::OnFinishSleep()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ELoopSource WaitSingleGeneric::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceInternalReserved1;
|
||||
}
|
||||
}
|
20
Source/Loop/WaitSingle.NT.hpp
Normal file
20
Source/Loop/WaitSingle.NT.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.NT.hpp
|
||||
Date: 2021-10-1
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class WaitSingleGeneric : public WaitSingleBase
|
||||
{
|
||||
public:
|
||||
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles, AuUInt &one) override;
|
||||
virtual void OnPresleep() override;
|
||||
virtual void OnFinishSleep() override;
|
||||
virtual ELoopSource GetType() override;
|
||||
};
|
||||
}
|
19
Source/Loop/WaitSingle.hpp
Normal file
19
Source/Loop/WaitSingle.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.hpp
|
||||
Date: 2021-10-2
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "WaitSingleBase.hpp"
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
#include "WaitSingle.NT.hpp"
|
||||
#elif defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include "WaitSingle.Linux.hpp"
|
||||
#else
|
||||
#define IMPL_WAIT_SINGLE_GEN
|
||||
#include "WaitSingle.Generic.hpp"
|
||||
#endif
|
23
Source/Loop/WaitSingleBase.cpp
Normal file
23
Source/Loop/WaitSingleBase.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.Generic.cpp
|
||||
Date: 2021-10-2
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "WaitSingleBase.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
bool WaitSingleBase::IsSignaled()
|
||||
{
|
||||
AuUInt one {};
|
||||
this->OnPresleep();
|
||||
auto handles = this->GetHandles();
|
||||
auto val = WaitForAtleastOne(handles, one);
|
||||
auto ret = this->OnTrigger(one, val);
|
||||
this->OnFinishSleep();
|
||||
return ret;
|
||||
}
|
||||
}
|
21
Source/Loop/WaitSingleBase.hpp
Normal file
21
Source/Loop/WaitSingleBase.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
/***
|
||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: WaitSingle.Generic.hpp
|
||||
Date: 2021-10-2
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include "ILoopSourceEx.hpp"
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class WaitSingleBase : public ILoopSourceEx
|
||||
{
|
||||
public:
|
||||
bool IsSignaled() override;
|
||||
|
||||
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles, AuUInt &one) = 0;
|
||||
};
|
||||
}
|
@ -10,21 +10,39 @@
|
||||
#include "Process.Linux.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <Source/Threading/Primitives/Semaphore.Unix.hpp>
|
||||
|
||||
static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
|
||||
unsigned int flags)
|
||||
{
|
||||
return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
|
||||
}
|
||||
|
||||
static inline int sys_pidfd_open(pid_t pid, unsigned int flags)
|
||||
{
|
||||
return syscall(__NR_pidfd_open, pid, flags);
|
||||
}
|
||||
|
||||
#ifndef P_PIDFD
|
||||
#define P_PIDFD 3
|
||||
#endif
|
||||
|
||||
namespace Aurora::Processes
|
||||
{
|
||||
class ProcessImpl : public IProcess
|
||||
{
|
||||
public:
|
||||
ProcessImpl(AuString cmd, AuList<AuString> args) : module_(cmd), args_(args);
|
||||
ProcessImpl(AuString cmd, AuList<AuString> args);
|
||||
~ProcessImpl();
|
||||
|
||||
void ShutdownPipes();
|
||||
|
||||
bool TryKill() override;
|
||||
bool Terminate() override;
|
||||
Aurora::Threading::IWaitable *AsWaitable() override;
|
||||
AuSPtr<Aurora::Threading::IWaitable> AsWaitable() override;
|
||||
|
||||
AuSInt GetExitCode() override;
|
||||
|
||||
@ -57,7 +75,7 @@ namespace Aurora::Processes
|
||||
{
|
||||
this->args_.insert(this->args_.begin(), cmd);
|
||||
|
||||
for (const auto &arg : this->args_)
|
||||
for (auto &arg : this->args_)
|
||||
{
|
||||
this->cargs_.push_back(arg.c_str());
|
||||
this->windows_ += arg + " ";
|
||||
@ -124,7 +142,7 @@ namespace Aurora::Processes
|
||||
return true;
|
||||
}
|
||||
|
||||
Aurora::Threading::IWaitable *ProcessImpl::AsWaitable()
|
||||
AuSPtr<Aurora::Threading::IWaitable> ProcessImpl::AsWaitable()
|
||||
{
|
||||
if (!this->thread_) return nullptr;
|
||||
return this->thread_->AsWaitable();
|
||||
@ -143,10 +161,13 @@ namespace Aurora::Processes
|
||||
|
||||
bool ProcessImpl::Read(bool error, void *buffer, AuUInt32 &len)
|
||||
{
|
||||
len = 0;
|
||||
auto handle = error ? pipeStdErr_[0] : pipeStdOut_[0];
|
||||
if (handle < 0) return false;
|
||||
len = read(handle, buffer, len);
|
||||
return ret;
|
||||
auto tmp = read(handle, buffer, len);
|
||||
if (tmp < 0) return false;
|
||||
len = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessImpl::Write(const void *buffer, AuUInt32 len)
|
||||
@ -163,7 +184,7 @@ namespace Aurora::Processes
|
||||
|
||||
if (type == ESpawnType::eSpawnAtomicOvermap)
|
||||
{
|
||||
execv(this->module_.c_str(), this->cargs_.data());
|
||||
execv(this->module_.c_str(), (char *const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
|
||||
SysPushErrorGen("execv didn't overwrite the process map, given {} ({})", this->module_, this->windows_);
|
||||
return false;
|
||||
}
|
||||
@ -196,7 +217,7 @@ namespace Aurora::Processes
|
||||
|
||||
pid_t pid;
|
||||
{
|
||||
Semaphore semaphore;
|
||||
Threading::Primitives::Semaphore semaphore;
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
@ -220,12 +241,12 @@ namespace Aurora::Processes
|
||||
close(std::exchange(pipeStdOut_[1], 0));
|
||||
}
|
||||
|
||||
if (type != ESpawnType::eSpawnSubProcessWorker)
|
||||
if (type != ESpawnType::eSpawnChildProcessWorker)
|
||||
{
|
||||
setsid();
|
||||
}
|
||||
|
||||
execv(this->module_.c_str(), this->cargs_.data());
|
||||
execv(this->module_.c_str(), (char * const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
|
||||
SysPushErrorGen("execv didn't overwrite the process map, given {} ({})", this->module_, this->windows_);
|
||||
return false;
|
||||
}
|
||||
@ -235,8 +256,8 @@ namespace Aurora::Processes
|
||||
}
|
||||
else
|
||||
{
|
||||
this->handle_ = pidfd_open(pid, 0);
|
||||
semaphore.unlock();
|
||||
this->handle_ = sys_pidfd_open(pid, 0);
|
||||
semaphore.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,4 +293,4 @@ namespace Aurora::Processes
|
||||
{
|
||||
SafeDelete<ProcessImpl *>(process);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,15 +36,35 @@
|
||||
#define AURORA_HAS_PTHREADS
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#if !defined(_LARGEFILE64_SOURCE)
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
#include <AuroraRuntime.hpp>
|
||||
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<intrin.h>)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#if __has_include(<emmintrin.h>)
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#if __has_include(<xmmintrin.h>)
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
#if __has_include(<immintrin.h>)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline Aurora::RuntimeStartInfo gRuntimeConfig;
|
||||
|
||||
using namespace Aurora::Console::Logging;
|
||||
|
@ -7,6 +7,7 @@
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "ConditionVariable.Generic.hpp"
|
||||
#include <Source/Time/Time.hpp>
|
||||
|
||||
#if !defined(_AURUNTIME_GENERICCV)
|
||||
|
||||
@ -30,7 +31,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool ConditionVariableImpl::WaitForSignal(AuUInt32 timeout)
|
||||
{
|
||||
auto mutex = reinterpret_cast<pthread_mutex_t>(mutex_->GetOSHandle());
|
||||
auto mutex = reinterpret_cast<pthread_mutex_t*>(mutex_->GetOSHandle());
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
@ -42,7 +43,7 @@ namespace Aurora::Threading::Primitives
|
||||
else
|
||||
{
|
||||
struct timespec tspec;
|
||||
ms2ts(&tspec, timeout);
|
||||
Time::ms2tsabs(&tspec, timeout);
|
||||
|
||||
auto ret = pthread_cond_timedwait(&pthreadCv_, mutex, &tspec);
|
||||
|
||||
@ -79,4 +80,4 @@ namespace Aurora::Threading::Primitives
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ namespace Aurora::Threading::Primitives
|
||||
else
|
||||
{
|
||||
struct timespec tspec;
|
||||
ms2ts(&tspec, timeout);
|
||||
Time::ms2tsabs(&tspec, timeout);
|
||||
|
||||
auto ret = pthread_mutex_timedlock(&value_, &tspec);
|
||||
if (ret != 0)
|
||||
@ -90,4 +90,4 @@ namespace Aurora::Threading::Primitives
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -10,6 +10,45 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
template<bool isread>
|
||||
void RWLockAccessView<isread>::Unlock()
|
||||
{
|
||||
if constexpr (isread)
|
||||
{
|
||||
parent_.UnlockRead();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_.UnlockWrite();
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isread>
|
||||
bool RWLockAccessView<isread>::Lock(AuUInt64 timeout)
|
||||
{
|
||||
if constexpr (isread)
|
||||
{
|
||||
return parent_.LockRead(timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent_.LockWrite(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isread>
|
||||
bool RWLockAccessView<isread>::TryLock()
|
||||
{
|
||||
if constexpr (isread)
|
||||
{
|
||||
return parent_.TryLockRead();
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent_.TryLockWrite();
|
||||
}
|
||||
}
|
||||
|
||||
RWLockImpl::RWLockImpl() : read_(*this), write_(*this)
|
||||
{
|
||||
|
||||
@ -170,4 +209,4 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
SafeDelete<RWLockImpl *>(waitable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,29 +20,9 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
}
|
||||
|
||||
bool Lock(AuUInt64 timeout) override
|
||||
{
|
||||
if constexpr (isread)
|
||||
{
|
||||
return parent_.LockRead(timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent_.LockWrite(timeout);
|
||||
}
|
||||
}
|
||||
bool Lock(AuUInt64 timeout) override;
|
||||
|
||||
bool TryLock() override
|
||||
{
|
||||
if constexpr (isread)
|
||||
{
|
||||
return parent_.TryLockRead();
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent_.TryLockWrite();
|
||||
}
|
||||
}
|
||||
bool TryLock() override;
|
||||
|
||||
bool HasOSHandle(AuMach &mach) override
|
||||
{
|
||||
@ -59,17 +39,7 @@ namespace Aurora::Threading::Primitives
|
||||
SysAssert(Lock(0));
|
||||
}
|
||||
|
||||
void Unlock() override
|
||||
{
|
||||
if constexpr (isread)
|
||||
{
|
||||
parent_.UnlockRead();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_.UnlockWrite();
|
||||
}
|
||||
}
|
||||
void Unlock() override;
|
||||
|
||||
private:
|
||||
RWLockImpl &parent_;
|
||||
@ -105,4 +75,4 @@ namespace Aurora::Threading::Primitives
|
||||
std::atomic<int> state_;
|
||||
std::atomic<bool> elevaterPending_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool Semaphore::HasOSHandle(AuMach &mach)
|
||||
{
|
||||
mach = reinterpret_cast<AuMach>(value_);
|
||||
mach = reinterpret_cast<AuMach>(&value_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool Semaphore::TryLock()
|
||||
{
|
||||
return sem_trywait(&_value) == 0;
|
||||
return sem_trywait(&value_) == 0;
|
||||
}
|
||||
|
||||
bool Semaphore::Lock(AuUInt64 timeout)
|
||||
@ -53,7 +53,7 @@ namespace Aurora::Threading::Primitives
|
||||
else
|
||||
{
|
||||
struct timespec tspec;
|
||||
ms2ts(&tspec, timeout);
|
||||
Time::ms2tsabs(&tspec, timeout);
|
||||
|
||||
auto ret = sem_timedwait(&value_, &tspec);
|
||||
if (ret != 0)
|
||||
@ -96,4 +96,4 @@ namespace Aurora::Threading::Primitives
|
||||
SafeDelete<Semaphore *>(waitable);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -401,7 +401,7 @@ namespace Aurora::Threading::Threads
|
||||
|
||||
#elif defined(AURORA_HAS_PTHREADS)
|
||||
|
||||
pthread_setname_np(_handle, name_.c_str());
|
||||
pthread_setname_np(handle_, name_.c_str());
|
||||
|
||||
#endif
|
||||
}
|
||||
@ -517,7 +517,7 @@ namespace Aurora::Threading::Threads
|
||||
|
||||
if (auto tid = unixThreadId_)
|
||||
{
|
||||
setpriority(PRIO_PROCESS, tid, val);
|
||||
setpriority(PRIO_PROCESS, tid, *val);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -620,4 +620,4 @@ namespace Aurora::Threading::Threads
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,10 +52,10 @@ namespace Aurora::Threading::Threads
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
#if defined(AURORA_COMPILER_MSVC) || defined(AURORA_COMPILER_CLANG)
|
||||
#define DEFINE_SPEEDY_TLS(type, name) static thread_local type name;
|
||||
#elif defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC)
|
||||
#define DEFINE_SPEEDY_TLS(type, name) __thread type name __attribute__((tls_model("initial-exec")));
|
||||
#elif defined(AURORA_COMPILER_GCC)
|
||||
#define DEFINE_SPEEDY_TLS(type, name) __thread type name __attribute__((tls_model("initial-exec")));
|
||||
#else
|
||||
#define DEFINE_SPEEDY_TLS(type, name) static thread_local type name;
|
||||
#endif
|
||||
@ -111,4 +111,4 @@ namespace Aurora::Threading::Threads
|
||||
{
|
||||
return reinterpret_cast<AuThreadId_t>(GetThread());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ static inline T DecodeEpoch(T auroraEpoch)
|
||||
template<typename Clock_t, typename Duration_t>
|
||||
static auto TimeFromDurationSinceEpoch(Duration_t in)
|
||||
{
|
||||
auto duration = std::chrono::duration_cast<Clock_t::duration>(in);
|
||||
auto duration = std::chrono::duration_cast<typename Clock_t::duration>(in);
|
||||
return std::chrono::time_point<Clock_t>(DecodeEpoch(duration));
|
||||
}
|
||||
|
||||
@ -99,6 +99,11 @@ namespace Aurora::Time
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 CTimeToMS(time_t time)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(sys_clock::from_time_t(time).time_since_epoch())).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuUInt64 CurrentInternalClock()
|
||||
{
|
||||
return high_res_clock::now().time_since_epoch().count();
|
||||
@ -194,7 +199,11 @@ namespace Aurora::Time
|
||||
auto timet = MSToCTime(time);
|
||||
if (UTC)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
auto tm = gmtime_s(&ret, &timet);
|
||||
#else
|
||||
auto tm = gmtime_r(&timet, &ret);
|
||||
#endif
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
SysAssert(!tm, "couldn't convert civil time");
|
||||
#else
|
||||
@ -211,7 +220,11 @@ namespace Aurora::Time
|
||||
#endif
|
||||
{
|
||||
LogWarn("Couldn't convert local civil time");
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
auto tm = gmtime_s(&ret, &timet);
|
||||
#else
|
||||
auto tm = gmtime_r(&timet, &ret);
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
SysAssert(!tm, "couldn't convert civil time");
|
||||
@ -247,4 +260,4 @@ namespace Aurora::Time
|
||||
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(std::chrono::system_clock::from_time_t(timet).time_since_epoch())).count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ namespace Aurora::Time
|
||||
return ull.QuadPart / 10000ULL - 12'643'550'100'000ULL;
|
||||
}
|
||||
|
||||
|
||||
#elif defined(AURORA_IS_POSIX_DERIVED)
|
||||
|
||||
static inline AuUInt32 ConvertUnixTimespecToMs(const struct timespec &spec)
|
||||
@ -32,5 +33,12 @@ namespace Aurora::Time
|
||||
ts->tv_nsec = (ms % 1000) * 1000000;
|
||||
}
|
||||
|
||||
static void ms2tsabs(struct timespec *ts, unsigned long ms)
|
||||
{
|
||||
ms += ConvertAuroraToUnixMS(CurrentClockMS());
|
||||
ts->tv_sec = ms / 1000;
|
||||
ts->tv_nsec = (ms % 1000) * 1000000;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue
Block a user