Merge remote-tracking branch 'origin/master'

This commit is contained in:
Reece Wilson 2021-10-06 14:48:38 +01:00
commit f968d6a75f
74 changed files with 842 additions and 219 deletions

1
.gitignore vendored
View File

@ -23,3 +23,4 @@ compile_flags.txt
*cmake
.intellij
.clion
Makefile

View File

@ -14,7 +14,7 @@
{
"if": "win32",
"then": {
"links": "Bcrypt.lib"
"links": ["Bcrypt.lib", "UxTheme.lib"]
}
}
]

View File

@ -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...);
};
@ -536,13 +570,6 @@ 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;
#endif
// 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;
};
#pragma endregion EASE_OF_READING
}

View File

@ -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");
}
}

View File

@ -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

View File

@ -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)

View File

@ -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>

View File

@ -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));
}

View File

@ -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)

View File

@ -22,7 +22,6 @@
#include <memory>
#include <optional>
#include <functional>
#include <intrin.h>
#include "../AuroraTypedefs.hpp"
#include "../AuroraUtils.hpp"

View File

@ -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

View File

@ -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

View File

@ -176,7 +176,12 @@ static const AuThreadId_t kThreadIdSpecialMask = AuThreadId_t(1) << AuThreadId_t
{
float elements[N];
float &operator [](int idx) const
float operator [](int idx) const
{
return elements[N];
}
float &operator [](int idx)
{
return elements[N];
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -7,7 +7,7 @@
***/
#include <Source/RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCx25519.hpp"
//#include "ECCx25519.hpp"
namespace Aurora::Crypto::ECC
{

View File

@ -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))

View File

@ -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?

View File

@ -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)

View File

@ -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)

View File

@ -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,11 +38,25 @@ 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)
@ -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)

View File

@ -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 (...)

View File

@ -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;
}

View File

@ -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 &parameters) override;
bool Write(const Memory::MemoryViewStreamRead & parameters) override;
void Close() override;
void Flush() override;

View File

@ -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;
}
@ -220,6 +232,7 @@ namespace Aurora::Locale::Encoding
{
AuStreamReadWrittenPair_t ret {};
#if defined(AU_HAS_MSFT_NATIONALLANGSUPPORT)
switch (page)
{
default:
@ -249,6 +262,7 @@ namespace Aurora::Locale::Encoding
break;
}
#endif
return ret;
}
}

View File

@ -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;
}

View File

@ -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

View 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
View 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
View 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
{
}

View File

@ -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 {};
}
}

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -7,6 +7,8 @@
***/
#pragma once
#include "WaitSingle.hpp"
#if defined(AURORA_IS_MODERNNT_DERIVED)
#include "LSEvent.NT.hpp"
// eventfd always atomically resets

View File

@ -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);
}
}

View File

@ -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;
};
}

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -7,6 +7,7 @@
***/
#pragma once
#include "WaitSingle.hpp"
#if defined(AURORA_IS_MODERNNT_DERIVED)
#include "LSSemaphore.NT.hpp"

View File

@ -6,6 +6,7 @@
Author: Reece
***/
#pragma once
#include "LSHandle.hpp"
namespace Aurora::Loop
{

View File

@ -1,5 +1,13 @@
/***
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"

14
Source/Loop/Loop.BSD.cpp Normal file
View 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
}

View File

@ -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

View File

@ -10,5 +10,8 @@
namespace Aurora::Loop
{
AUKN_SYM AuList<AuSPtr<ILoopSource>> WaitMultipleObjects(const AuList<AuSPtr<ILoopSource>> &objects, AuUInt32 timeout)
{
return {};
}
}

View File

@ -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
}

View File

@ -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

View 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;
};
}

View 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
{
}

View 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
{
}

View 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;
}
}

View 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;
};
}

View 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

View 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;
}
}

View 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;
};
}

View File

@ -11,20 +11,38 @@
#include <unistd.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();
}
}

View File

@ -36,15 +36,35 @@
#define AURORA_HAS_PTHREADS
#define _FILE_OFFSET_BITS 64
#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;

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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_;

View File

@ -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)

View File

@ -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
}

View File

@ -52,9 +52,9 @@ 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)
#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;

View File

@ -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");

View File

@ -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
}