[*] Begin resolving 8 months of Linux neglect

This commit is contained in:
Reece Wilson 2023-08-11 16:51:42 +01:00
parent 7100c807c8
commit 1f173a8799
47 changed files with 815 additions and 379 deletions

View File

@ -177,7 +177,7 @@ protected:
friend struct __detail::FutureAccessor;
CppFun<T>::B &GetValue()
typename CppFun<T>::B &GetValue()
{
return value;
}
@ -316,7 +316,7 @@ private:
this->pid = AuAsync::GetCurrentWorkerPId();
}
CppFun<T>::B value;
typename CppFun<T>::B value;
ErrorStore_t errorValue;
AuThreadPrimitives::Mutex mutex;

View File

@ -35,6 +35,22 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize32NTCond = 20;
static const auto kPrimitiveSize32NTCondMutex = 8;
static const auto kPrimitiveSize64LinuxMutex = 16;
static const auto kPrimitiveSize64LinuxSemaphore = 16;
static const auto kPrimitiveSize64LinuxCS = 128;
static const auto kPrimitiveSize64LinuxEvent = 152;
static const auto kPrimitiveSize64LinuxRWLock = 200;
static const auto kPrimitiveSize64LinuxCond = 88;
static const auto kPrimitiveSize64LinuxCondMutex = 48;
static const auto kPrimitiveSize32LinuxMutex = 8;
static const auto kPrimitiveSize32LinuxSemaphore = 8;
static const auto kPrimitiveSize32LinuxCS = 128;
static const auto kPrimitiveSize32LinuxEvent = 152;
static const auto kPrimitiveSize32LinuxRWLock = 200;
static const auto kPrimitiveSize32LinuxCond = 88;
static const auto kPrimitiveSize32LinuxCondMutex = 48;
// TODO: Other platforms...
#else
@ -64,13 +80,33 @@ namespace Aurora::Threading::Primitives
#define AURT_ENABLE_HYPER_MUTEX
#elif defined(AURORA_PLATFORM_LINUX)
static const auto kPrimitiveSize64Mutex = kPrimitiveSize64LinuxMutex;
static const auto kPrimitiveSize64Semaphore = kPrimitiveSize64LinuxSemaphore;
static const auto kPrimitiveSize64CS = kPrimitiveSize64LinuxCS;
static const auto kPrimitiveSize64Event = kPrimitiveSize64LinuxEvent;
static const auto kPrimitiveSize64RWLock = kPrimitiveSize64LinuxRWLock;
static const auto kPrimitiveSize64Cond = kPrimitiveSize64LinuxCond;
static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64LinuxCondMutex;
static const auto kPrimitiveSize32Mutex = kPrimitiveSize32LinuxMutex;
static const auto kPrimitiveSize32Semaphore = kPrimitiveSize32LinuxSemaphore;
static const auto kPrimitiveSize32CS = kPrimitiveSize32LinuxCS;
static const auto kPrimitiveSize32Event = kPrimitiveSize32LinuxEvent;
static const auto kPrimitiveSize32RWLock = kPrimitiveSize32LinuxRWLock;
static const auto kPrimitiveSize32Cond = kPrimitiveSize32LinuxCond;
static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32LinuxCondMutex;
#define AURT_ENABLE_HYPER_MUTEX
#else
static const auto kPrimitiveSize64Mutex = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64Semaphore = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64CS = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64Event = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64 * 2;
static const auto kPrimitiveSize64Cond = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64CondMutex = kDefaultPrimitiveSize64;

View File

@ -187,7 +187,10 @@ namespace Aurora::Async
void DeinitSched()
{
gThread->SendExitSignal();
if (gThread)
{
gThread->SendExitSignal();
}
gSchedCondvar->Broadcast();
gThread.reset();
}

View File

@ -21,7 +21,6 @@ namespace Crypto
yarrow_start(&gPrng);
gHashTiger = register_hash(&tiger_desc);
register_hash(&md5_desc);
gHashSha1 = register_hash(&sha1_desc);
gHashSha256 = register_hash(&sha256_desc);
gHashSha384 = register_hash(&sha384_desc);

View File

@ -123,8 +123,9 @@ static void Pump()
::LinuxSuperSecretIOTick();
#endif
#if defined(AURORA_PLATFORM_WIN32)
Aurora::Win32DropSchedulerResolution();
#endif
}
static void RuntimeLateClean();

View File

@ -197,7 +197,7 @@ namespace Aurora::Compression
{
size_t outNext {};
uint8_t *pOut {};
while (outNext == 0 || BrotliEncoderHasMoreOutput(this->pState));
while (outNext == 0 || BrotliEncoderHasMoreOutput(this->pState))
{
auto [pMainDOut, uMainDOutLength] = this->GetDOutPair();

View File

@ -10,12 +10,11 @@
namespace Aurora::Debug
{
void PlatformHandleFatal(bool fatal)
void PlatformHandleFatal(bool fatal, bool bNoExit)
{
}
void InitUNIX()
{

View File

@ -39,10 +39,10 @@ namespace Aurora::Grug
pArrow->pCallback = pCallback;
pArrow->pCallbackRunaway = pCallbackRunaway;
#if defined(ARROW_NO_MUTEX)
SignalSafeSleepLockYield(&pArrow->spinSemaphore);
#else
#if !defined(ARROW_NO_MUTEX)
SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer());
#else
SignalSafeSleepLockYield(&pArrow->spinSemaphore);
#endif
{
@ -113,7 +113,9 @@ namespace Aurora::Grug
auto lastCallback = last->pCallbackRunaway;
last->spinSemaphore.Unlock();
#if !defined(ARROW_NO_MUTEX)
last->spinSemaphore2->Unlock();
#endif
gReservedArrows.pop_back();

View File

@ -93,6 +93,7 @@ namespace Aurora::IO
if (create.bDirectIOMode)
{
dwFlags |= FILE_FLAG_NO_BUFFERING;
this->bDirectIOMode = true;
}
if (!dwFlags)

View File

@ -0,0 +1,174 @@
/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuIOHandle.Unix.cpp
Date: 2023-8-11
Author: Reece
***/
#include <RuntimeInternal.hpp>
#include "AuIOHandle.hpp"
#include "AuIOHandle.Unix.hpp"
#include "FS/FS.hpp"
#include "FS/FileAdvisory.Unix.hpp"
#include "FS/FileStream.Unix.hpp"
#include <fcntl.h>
namespace Aurora::IO
{
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
{
int fd = dup(uOSHandle);
if (fd < 0)
{
return 0;
}
return AuUInt64(fd);
}
void AFileHandle::CloseHandle(AuUInt64 uOSHandle)
{
int fd = (int)uOSHandle;
if (fd < 0)
{
return;
}
::close(fd);
}
struct UnixIOHandle final : AFileHandle
{
bool InitFromPath(HandleCreate create) override
{
int iFileDescriptor { -1 };
if (create.path.empty())
{
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
return false;
}
if (!FS::EFileOpenModeIsValid(create.eMode))
{
SysPushErrorParam("Invalid open mode");
return false;
}
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
{
SysPushErrorParam("Invalid lock mode");
return false;
}
auto pathex = FS::NormalizePathRet(create.path);
if (pathex.empty())
{
SysPushErrorMemory();
return false;
}
if (create.bAsyncHandle ||
create.bDirectIOMode)
{
this->bDirectIO = true;
}
switch (create.eMode)
{
case FS::EFileOpenMode::eRead:
{
break;
}
case FS::EFileOpenMode::eReadWrite:
case FS::EFileOpenMode::eWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{
if (AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
break;
}
};
iFileDescriptor = ::open(pathex.c_str(),
(create.eMode == FS::EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC | (this->bDirectIO ? O_DIRECT : 0),
0664);
if (iFileDescriptor < 0)
{
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
return false;
}
if (!FS::ApplyDumbAdvisoryLock(iFileDescriptor, create.eAdvisoryLevel))
{
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
::close(iFileDescriptor);
return false;
}
if (create.bFailIfNonEmptyFile)
{
if (FS::PosixGetLength(iFileDescriptor))
{
SysPushErrorResourceExists("File {} already exists", create.path);
::close(iFileDescriptor);
return false;
}
}
switch (create.eMode)
{
case FS::EFileOpenMode::eRead:
{
this->uOSReadHandle = AuUInt64(iFileDescriptor);
break;
}
case FS::EFileOpenMode::eReadWrite:
{
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
this->uOSReadHandle = AuUInt64(iFileDescriptor);
break;
}
case FS::EFileOpenMode::eWrite:
{
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
break;
}
};
this->bIsAsync = create.bAsyncHandle;
this->path = create.path;
return this->IsValid();
}
};
AUKN_SYM IIOHandle *IOHandleNew()
{
return _new UnixIOHandle();
}
AUKN_SYM void IOHandleRelease(IIOHandle *pIOHandle)
{
AuSafeDelete<UnixIOHandle *>(pIOHandle);
}
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, IOHandle, UnixIOHandle)
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuIOHandle.Unix.hpp
Date: 2023-8-11
Author: Reece
***/
#pragma once
namespace Aurora::IO
{
}

View File

@ -7,6 +7,11 @@
***/
#pragma once
namespace Aurora::IO::IPC
{
struct IPCPipeImpl;
}
namespace Aurora::IO
{
struct AFileHandle : IIOHandle
@ -48,6 +53,8 @@ namespace Aurora::IO
AuSPtr<IIOHandle> pThat;
bool bIsAsync {};
AuString path;
IPC::IPCPipeImpl *pIPCPipe {};
bool bDirectIO {};
protected:
// Implement me:

View File

@ -17,9 +17,12 @@
#include "FileStream.Unix.hpp"
#include "Async.Linux.hpp"
#include <Source/IO/IPC/AuIPCPipe.Unix.hpp>
#include <Source/IO/AuIOHandle.hpp>
namespace Aurora::IO::FS
{
#define IPC_PIPE AuStaticCast<AFileHandle>(this->pHandle_)->pIPCPipe
struct LinuxAsyncFileTransactionLoopSource : Aurora::IO::Loop::LSEvent
{
LinuxAsyncFileTransactionLoopSource(AuSPtr<LinuxAsyncFileTransaction> that);
@ -38,16 +41,16 @@ namespace Aurora::IO::FS
AuList<AuUInt> handles_;
};
LinuxAsyncFileTransactionLoopSource::LinuxAsyncFileTransactionLoopSource(AuSPtr<LinuxAsyncFileTransaction> that) : caller_(that), Loop::LSEvent(false, false, true)
LinuxAsyncFileTransactionLoopSource::LinuxAsyncFileTransactionLoopSource(AuSPtr<LinuxAsyncFileTransaction> that) :
caller_(that),
Loop::LSEvent(false, false, true)
{
if (that)
{
auto possiblePipe = that->GetFileHandle()->pIPCPipe;
if (possiblePipe)
if (auto pPipe = AuStaticCast<AFileHandle>(that->GetFileHandle())->pIPCPipe)
{
this->bExMode = true;
this->handles_ = {possiblePipe->GetPreemptFd(), Loop::LSEvent::GetHandle()};
this->handles_ = {pPipe->GetPreemptFd(), Loop::LSEvent::GetHandle()};
}
}
}
@ -94,80 +97,9 @@ namespace Aurora::IO::FS
{
}
FileHandle::~FileHandle()
void LinuxAsyncFileStream::Init(const AuSPtr<IIOHandle> &handle)
{
if ((this->readHandle != 0) &&
(this->readHandle != -1))
{
::close(this->readHandle);
}
if ((this->writeHandle != 0) &&
(this->writeHandle != -1) &&
(this->writeHandle != this->readHandle))
{
::close(this->writeHandle);
}
this->readHandle = this->writeHandle = -1;
}
bool FileHandle::Init(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock)
{
int fileHandle;
int fOpenMode;
auto pathex = NormalizePathRet(path);
if (pathex.empty())
{
return false;
}
fOpenMode = openMode == EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT);
if (bDirectIO)
{
fOpenMode |= O_DIRECT;
}
fileHandle = ::open(pathex.c_str(),
fOpenMode,
0664);
if (fileHandle == -1)
{
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
return false;
}
if (!ApplyDumbAdvisoryLock(fileHandle, lock))
{
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
return false;
}
this->directIO = bDirectIO;
this->readHandle = this->writeHandle = fileHandle;
this->readOnly = openMode == EFileOpenMode::eRead;
return true;
}
void FileHandle::Init(int read, int write)
{
this->readHandle = read;
this->writeHandle = write;
this->directIO = true;
this->readOnly = false;
}
AuSPtr<FileHandle> LinuxAsyncFileStream::GetHandle()
{
return handle_;
}
void LinuxAsyncFileStream::Init(const AuSPtr<FileHandle> &handle)
{
this->handle_ = handle;
this->pHandle_ = handle;
}
AuSPtr<IAsyncTransaction> LinuxAsyncFileStream::NewTransaction()
@ -178,7 +110,7 @@ namespace Aurora::IO::FS
return {};
}
if (!shared->Init(this->handle_))
if (!shared->Init(this->pHandle_))
{
return {};
}
@ -188,32 +120,53 @@ namespace Aurora::IO::FS
bool LinuxAsyncFileStream::BlockingTruncate(AuUInt64 length)
{
return ::ftruncate(this->handle_->writeHandle, length) != -1;
}
bool LinuxAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite &parameters)
{
if (this->handle_->bReadLock)
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
if (!iOptSafe)
{
return false;
}
if (this->handle_->pIPCPipe)
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
if (this->handle_->pIPCPipe->LIOS_PopOne())
SysPushErrorUninitialized();
return false;
}
return ::ftruncate(fd, length) != -1;
}
bool LinuxAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite &parameters)
{
auto iOptSafe = this->pHandle_->GetOSReadHandleSafe();
if (!iOptSafe)
{
return false;
}
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
return false;
}
if (IPC_PIPE)
{
if (IPC_PIPE->LIOS_PopOne())
{
parameters.outVariable = 0;
return true;
}
}
if (!PosixSetOffset(this->handle_->readHandle, offset))
if (!PosixSetOffset(fd, offset))
{
return false;
}
AuUInt32 read;
if (!PosixRead(this->handle_->readHandle, parameters.ptr, parameters.length, &read))
if (!PosixRead(fd, parameters.ptr, parameters.length, &read))
{
return false;
}
@ -223,18 +176,26 @@ namespace Aurora::IO::FS
bool LinuxAsyncFileStream::BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead &parameters)
{
if (this->handle_->bWriteLock)
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
if (!iOptSafe)
{
return false;
}
if (!PosixSetOffset(this->handle_->writeHandle, offset))
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
return false;
}
if (!PosixSetOffset(fd, offset))
{
return false;
}
AuUInt32 read;
if (!PosixWrite(this->handle_->writeHandle, parameters.ptr, parameters.length, &read))
if (!PosixWrite(fd, parameters.ptr, parameters.length, &read))
{
return false;
}
@ -242,9 +203,9 @@ namespace Aurora::IO::FS
return true;
}
bool LinuxAsyncFileTransaction::Init(const AuSPtr<FileHandle> &handle)
bool LinuxAsyncFileTransaction::Init(const AuSPtr<IIOHandle> &handle)
{
this->handle_ = handle;
this->pHandle_ = handle;
this->loopSource_ = AuMakeShared<LinuxAsyncFileTransactionLoopSource>(AuSharedFromThis());
return bool(this->loopSource_);
}
@ -262,16 +223,16 @@ namespace Aurora::IO::FS
return false;
}
auto fd = this->handle_->readHandle;
if (fd == -1)
auto iOptSafe = this->pHandle_->GetOSReadHandleSafe();
if (!iOptSafe)
{
SysPushErrorUninitialized();
return false;
}
if (this->handle_->bReadLock)
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
return false;
}
@ -293,9 +254,9 @@ namespace Aurora::IO::FS
LIOS_Init(AuSharedFromThis());
SetMemory(memoryView);
if (this->handle_->pIPCPipe)
if (IPC_PIPE)
{
if (this->handle_->pIPCPipe->LIOS_PopOne())
if (IPC_PIPE->LIOS_PopOne())
{
LIOS_SendProcess(0, false, errno);
return true;
@ -304,7 +265,7 @@ namespace Aurora::IO::FS
offset += this->uBaseOffset;
if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(this->handle_->pIPCPipe)))
if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(IPC_PIPE)))
{
LIOS_SendProcess(0, true, errno);
return true;
@ -328,12 +289,13 @@ namespace Aurora::IO::FS
return false;
}
if (this->handle_->bWriteLock)
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
if (!iOptSafe)
{
return false;
}
auto fd = this->handle_->writeHandle;
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
@ -398,11 +360,11 @@ namespace Aurora::IO::FS
if (read)
{
if (this->handle_->pIPCPipe)
if (IPC_PIPE)
{
// Return value intentionally ignored
// We just need to poke on read...
this->handle_->pIPCPipe->LIOS_PopOne();
IPC_PIPE->LIOS_PopOne();
}
}
@ -471,9 +433,9 @@ namespace Aurora::IO::FS
return WaitMultiple(files, timeout);
}
AuSPtr<FileHandle> LinuxAsyncFileTransaction::GetFileHandle()
AuSPtr<IIOHandle> LinuxAsyncFileTransaction::GetFileHandle()
{
return this->handle_;
return this->pHandle_;
}
AuSPtr<Loop::ILoopSource> LinuxAsyncFileTransaction::NewLoopSource()
@ -483,38 +445,35 @@ namespace Aurora::IO::FS
AUKN_SYM IAsyncFileStream *OpenAsyncNew(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock)
{
AuSPtr<FileHandle> fileHandle;
LinuxAsyncFileStream *stream;
if (path.empty())
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorParam("Empty path");
return {};
SysPushErrorMemory();
return nullptr;
}
if (!EFileOpenModeIsValid(openMode))
{
SysPushErrorParam("Invalid open mode");
return {};
}
AuIO::IIOHandle::HandleCreate createhandle(path);
createhandle.eAdvisoryLevel = lock;
createhandle.eMode = openMode;
createhandle.bFailIfNonEmptyFile = false;
createhandle.bDirectIOMode = bDirectIO;
createhandle.bAsyncHandle = true;
fileHandle = AuMakeShared<FileHandle>();
if (!fileHandle->Init(path, openMode, bDirectIO, lock))
if (!pHandle->InitFromPath(createhandle))
{
SysPushErrorNested();
return {};
return nullptr;
}
stream = _new LinuxAsyncFileStream();
if (!stream)
auto pStream = _new LinuxAsyncFileStream();
if (!pStream)
{
SysPushErrorMem();
return {};
SysPushErrorMemory();
return nullptr;
}
stream->Init(fileHandle);
return stream;
pStream->Init(pHandle);
return pStream;
}
AUKN_SYM void OpenAsyncRelease(IAsyncFileStream *handle)

View File

@ -17,25 +17,6 @@ namespace Aurora::IO::FS
struct LinuxAsyncFileTransaction;
struct LinuxAsyncFileTransactionLoopSource;
struct FileHandle
{
~FileHandle();
bool Init(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock);
void Init(int read, int write);
int readHandle {-1};
int writeHandle {-1};
AuString path;
bool readOnly;
bool directIO;
IPC::IPCPipeImpl *pIPCPipe {};
bool bNoOwns { false };
bool bWriteLock { false };
bool bReadLock { false };
};
struct LinuxAsyncFileStream : IAsyncFileStream
{
AuSPtr<IAsyncTransaction> NewTransaction() override;
@ -43,12 +24,12 @@ namespace Aurora::IO::FS
bool BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite &parameters) override;
bool BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead &parameters) override;
void Init(const AuSPtr<FileHandle> &handle);
void Init(const AuSPtr<IIOHandle> &handle);
AuSPtr<FileHandle> GetHandle();
AuSPtr<IIOHandle> GetHandle();
private:
AuSPtr<FileHandle> handle_;
AuSPtr<IIOHandle> pHandle_;
};
@ -56,7 +37,7 @@ namespace Aurora::IO::FS
{
~LinuxAsyncFileTransaction();
bool Init(const AuSPtr<FileHandle> &handle);
bool Init(const AuSPtr<IIOHandle> &handle);
bool StartRead(AuUInt64 offset, const AuSPtr<AuMemoryViewWrite> &memoryView) override;
bool StartWrite(AuUInt64 offset, const AuSPtr<AuMemoryViewRead> &memoryView) override;
@ -78,14 +59,14 @@ namespace Aurora::IO::FS
void Reset() override;
void DispatchCb();
AuSPtr<FileHandle> GetFileHandle();
AuSPtr<IIOHandle> GetFileHandle();
void SetBaseOffset(AuUInt64 uBaseOffset) override;
virtual void LIOS_Process(AuUInt32 read, bool failure, int err, bool mark) override;
private:
AuSPtr<FileHandle> handle_;
AuSPtr<IIOHandle> pHandle_;
AuUInt64 lastAbstractOffset_ {};
AuUInt32 lastFinishedStat_ {};
AuUInt64 uBaseOffset {};

View File

@ -302,8 +302,8 @@ namespace Aurora::IO::FS
AUKN_SYM bool Relink(const AuString &src, const AuString &dest)
{
auto normalizedDestPath = NormalizePathRet(dest);
CreateDirectories(destPathNormalized, true);
return ::rename(NormalizePathRet(src).c_str(), destPathNormalized.c_str()) != -1;
CreateDirectories(normalizedDestPath, true);
return ::rename(NormalizePathRet(src).c_str(), normalizedDestPath.c_str()) != -1;
}
#if defined(AURORA_IS_LINUX_DERIVED)
@ -419,9 +419,9 @@ namespace Aurora::IO::FS
#if defined(AURORA_IS_LINUX_DERIVED)
stat.createdNs = AuTime::CTimeNSNormalize(s.st_ctime_nsec);
stat.modifiedNs = AuTime::CTimeNSNormalize(s.st_mtime_nsec);
stat.accessedNs = AuTime::CTimeNSNormalize(s.st_atime_nsec);
stat.createdNs = AuTime::CTimeNSNormalize(s.st_ctim.tv_nsec);
stat.modifiedNs = AuTime::CTimeNSNormalize(s.st_mtim.tv_nsec);
stat.accessedNs = AuTime::CTimeNSNormalize(s.st_atim.tv_nsec);
#else
stat.createdNs = AuMSToNS<AuUInt64>(Time::CTimeToMS(s.st_ctime));
stat.modifiedNs = AuMSToNS<AuUInt64>(Time::CTimeToMS(s.st_mtime));

View File

@ -66,8 +66,8 @@ namespace Aurora::IO::FS
timeval timeVals[2];
ConvertFileTime(&timeVals[0], auStat.accessed, times.accessedNs);
ConvertFileTime(&timeVals[1], auStat.modified, times.modifiedNs);
ConvertFileTime(&timeVals[0], auStat.accessedNs, times.accessedNs);
ConvertFileTime(&timeVals[1], auStat.modifiedNs, times.modifiedNs);
bool bRet = ::utimes(pathex.c_str(), timeVals) == 0;
if (!bRet)

View File

@ -19,7 +19,7 @@ namespace Aurora::IO::FS
AuString buffer;
auto srcPath = NormalizePathRet(path);
if (pathex.empty())
if (srcPath.empty())
{
return {};
}
@ -30,7 +30,7 @@ namespace Aurora::IO::FS
return {};
}
auto length = ::listxattr(srcPath.c_str(), attr.c_str(), buffer.data(), buffer.size(), 0 /*no follow symlinks*/);
auto length = ::listxattr(srcPath.c_str(), buffer.data(), buffer.size());
if (length < 0)
{
SysPushErrorIO("Error listing attributes");
@ -51,12 +51,12 @@ namespace Aurora::IO::FS
AuByteBuffer buffer;
auto srcPath = NormalizePathRet(path);
if (pathex.empty())
if (srcPath.empty())
{
return {};
}
auto length = ::getxattr(srcPath.c_str(), attr.c_str(), nullptr, 0, 0 /*no follow symlinks*/);
auto length = ::getxattr(srcPath.c_str(), attr.c_str(), nullptr, 0);
if (length < 0)
{
SysPushErrorIO("Error reading attribute");
@ -74,7 +74,7 @@ namespace Aurora::IO::FS
return {};
}
length = ::getxattr(srcPath.c_str(), attr.c_str(), buffer.base, length, 0 /*no follow symlinks*/);
length = ::getxattr(srcPath.c_str(), attr.c_str(), buffer.base, length);
if (length < 0)
{
SysPushErrorIO("Error reading attribute");
@ -89,7 +89,7 @@ namespace Aurora::IO::FS
AUKN_SYM bool FileAttrsSet(const AuString &path, const AuString &attr, const Memory::MemoryViewRead &view)
{
auto srcPath = NormalizePathRet(path);
if (pathex.empty())
if (srcPath.empty())
{
return false;
}
@ -112,7 +112,7 @@ namespace Aurora::IO::FS
AUKN_SYM bool FileAttrsDel(const AuString &path, const AuString &attr)
{
auto srcPath = NormalizePathRet(path);
if (pathex.empty())
if (srcPath.empty())
{
return false;
}

View File

@ -126,57 +126,81 @@ namespace Aurora::IO::FS
Close();
}
bool PosixFileStream::Init(int handle, const AuString &path)
bool PosixFileStream::Init(AuSPtr<IIOHandle> pHandle)
{
AuCtorCode_t code;
this->handle_ = handle;
this->path_ = AuTryConstruct<AuString>(code, path);
if (!code)
{
return false;
}
this->pHandle_ = pHandle;
return true;
}
AuUInt64 PosixFileStream::GetOffset()
{
AU_LOCK_GUARD(this->spinlock_);
if (this->handle_ == -1)
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
if (!iOptSafe)
{
SysPushErrorUninitialized();
return 0;
iOptSafe = this->pHandle_->GetOSReadHandleSafe();
}
return PosixGetOffset(this->handle_);
if (!iOptSafe)
{
return false;
}
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
return false;
}
return PosixGetOffset(fd);
}
bool PosixFileStream::SetOffset(AuUInt64 offset)
{
AU_LOCK_GUARD(this->spinlock_);
if (this->handle_ == -1)
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
if (!iOptSafe)
{
iOptSafe = this->pHandle_->GetOSReadHandleSafe();
}
if (!iOptSafe)
{
SysPushErrorUninitialized();
return 0;
return false;
}
return PosixSetOffset(this->handle_, offset);
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
return false;
}
return PosixSetOffset(fd, offset);
}
AuUInt64 PosixFileStream::GetLength()
{
AU_LOCK_GUARD(this->spinlock_);
if (this->handle_ == -1)
auto iOptSafe = this->pHandle_->GetOSReadHandleSafe();
if (!iOptSafe)
{
return false;
}
auto fd = (int)iOptSafe.Value();
if (fd == -1)
{
SysPushErrorUninitialized();
return 0;
return false;
}
return PosixGetLength(this->handle_);
return PosixGetLength(fd);
}
bool PosixFileStream::Read(const Memory::MemoryViewStreamWrite &parameters)
@ -185,7 +209,14 @@ namespace Aurora::IO::FS
parameters.outVariable = 0;
if (this->handle_ == -1)
if (!this->pHandle_)
{
SysPushErrorUninitialized();
return 0;
}
int fd = this->GetUnixHandle();
if (fd == -1)
{
SysPushErrorUninitialized();
return 0;
@ -199,7 +230,7 @@ namespace Aurora::IO::FS
int blockSize = AuMin(kFileCopyBlock, length);
if (!PosixRead(handle_, &reinterpret_cast<char *>(parameters.ptr)[offset], blockSize, &read))
if (!PosixRead(fd, &reinterpret_cast<char *>(parameters.ptr)[offset], blockSize, &read))
{
SysPushErrorNested("File Error: {}", path_);
break;
@ -222,7 +253,14 @@ namespace Aurora::IO::FS
{
AU_LOCK_GUARD(this->spinlock_);
if (this->handle_ == -1)
if (!this->pHandle_)
{
SysPushErrorUninitialized();
return 0;
}
int fd = this->GetUnixHandle();
if (fd == -1)
{
SysPushErrorUninitialized();
return 0;
@ -238,9 +276,9 @@ namespace Aurora::IO::FS
int blockSize = AuMin(AuUInt(kFileCopyBlock), length);
if (!PosixWrite(this->handle_, &reinterpret_cast<const char *>(parameters.ptr)[offset], blockSize, &written))
if (!PosixWrite(fd, &reinterpret_cast<const char *>(parameters.ptr)[offset], blockSize, &written))
{
SysPushErrorNested("File Error: {}", path_);
SysPushErrorNested("File Error: {}", this->pHandle_->GetPath());
return false;
}
@ -265,26 +303,40 @@ namespace Aurora::IO::FS
void PosixFileStream::Close()
{
int handle = AuExchange(this->handle_, -1);
if (handle != -1)
{
::close(handle);
}
auto pHandle = this->pHandle_;
AuResetMember(this->pHandle_);
if (AuExchange(this->bMadeTemporary, false))
{
::unlink(this->path_.c_str());
if (pHandle)
{
::unlink(pHandle->GetPath().c_str());
}
}
}
void PosixFileStream::Flush()
{
::fsync(this->handle_);
int fd = this->GetUnixHandle();
if (fd == -1)
{
SysPushErrorUninitialized();
return;
}
::fsync(fd);
}
void PosixFileStream::WriteEoS()
{
::ftruncate(this->handle_, GetOffset());
int fd = this->GetUnixHandle();
if (fd == -1)
{
SysPushErrorUninitialized();
return;
}
::ftruncate(fd, GetOffset());
}
void PosixFileStream::MakeTemporary()
@ -292,70 +344,72 @@ namespace Aurora::IO::FS
this->bMadeTemporary = true;
}
int PosixFileStream::GetHandle()
int PosixFileStream::GetUnixHandle()
{
return this->handle_;
return this->pHandle_ ?
(int)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)-1)) :
-1;
}
static IFileStream *OpenNewEx(const AuString &path, EFileOpenMode openMode, EFileAdvisoryLockLevel lock, bool bCheck)
AuSPtr<IIOHandle> PosixFileStream::GetHandle()
{
auto pathex = NormalizePathRet(path);
return this->pHandle_;
}
if (openMode != EFileOpenMode::eRead)
AUKN_SYM AuSPtr<IFileStream> OpenBlockingFileStreamFromHandle(AuSPtr<IIOHandle> pIOHandle)
{
auto pStream = AuMakeShared<PosixFileStream>();
if (!pStream)
{
CreateDirectories(pathex, true);
SysPushErrorMemory();
return nullptr;
}
if (bCheck)
pStream->Init(pIOHandle);
return pStream;
}
static IFileStream *OpenNewEx(const AuString &path,
EFileOpenMode openMode,
EFileAdvisoryLockLevel lock,
bool bCheck)
{
try
{
if (FileExists(path))
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorIO("Couldn't open file: {}. Already exists.", path);
return false;
SysPushErrorMemory();
return nullptr;
}
}
auto fileHandle = ::open(pathex.c_str(),
(openMode == EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC,
0664);
AuIO::IIOHandle::HandleCreate createhandle(path);
createhandle.eAdvisoryLevel = lock;
createhandle.eMode = openMode;
createhandle.bFailIfNonEmptyFile = bCheck;
createhandle.bDirectIOMode = false;
createhandle.bAsyncHandle = false;
if (fileHandle < 0)
{
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
return nullptr;
}
if (!ApplyDumbAdvisoryLock(fileHandle, lock))
{
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
return nullptr;
}
if (bCheck)
{
if (PosixGetLength(fileHandle))
if (!pHandle->InitFromPath(createhandle))
{
SysPushErrorIO("Couldn't open file: {}. Already exists.", path);
return false;
SysPushErrorNested();
return nullptr;
}
}
auto stream = _new PosixFileStream();
if (!stream)
auto pStream = _new PosixFileStream();
if (!pStream)
{
SysPushErrorMemory();
return nullptr;
}
pStream->Init(pHandle);
return pStream;
}
catch (...)
{
::close(fileHandle);
SysPushErrorMem("{}", path);
return nullptr;
}
if (!stream->Init(fileHandle, pathex))
{
delete stream;
SysPushErrorGeneric("{}", path);
return nullptr;
}
return stream;
}
AUKN_SYM IFileStream *CreateNew(const AuString &path)

View File

@ -13,6 +13,7 @@ namespace Aurora::IO::FS
{
// Code-sharing for async API fallbacks...
bool PosixSetOffset(int fd, AuUInt64 offset);
AuUInt64 PosixGetLength(int fd);
bool PosixRead(int fd, void *buf, AuUInt32 count, AuUInt32 *pRead);
bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten);
@ -20,7 +21,7 @@ namespace Aurora::IO::FS
{
~PosixFileStream();
bool Init(int handle, const AuString &path);
bool Init(AuSPtr<IIOHandle> pHandle);
AuUInt64 GetOffset() override;
bool SetOffset(AuUInt64 offset) override;
@ -31,11 +32,11 @@ namespace Aurora::IO::FS
void Flush() override;
void WriteEoS() override;
void MakeTemporary() override;
AuSPtr<IIOHandle> GetHandle() override;
int GetUnixHandle();
int GetHandle();
private:
int handle_ = -1;
AuSPtr<IIOHandle> pHandle_;
AuString path_;
AuThreadPrimitives::SpinLock spinlock_;
bool bMadeTemporary {};

View File

@ -10,6 +10,10 @@
#include "FileTrust.Unix.hpp"
#include <sys/xattr.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
namespace Aurora::IO::FS
{

View File

@ -13,6 +13,7 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <Source/IO/AuIOHandle.hpp>
namespace Aurora::IO::IPC
{
@ -127,14 +128,16 @@ namespace Aurora::IO::IPC
}
#endif
this->fsHandle_ = AuMakeShared<IO::FS::FileHandle>();
this->fsHandle_ = AuIO::IOHandleShared();
SysAssert(this->fsHandle_);
this->fsStream_ = AuMakeShared<IO::FS::LinuxAsyncFileStream>();
this->fsHandle_->pIPCPipe = this;
AuStaticCast<AFileHandle>(this->fsHandle_)->pIPCPipe = this;
this->fsHandle_->Init(fds2[0], fds2[1]);
this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]);
this->fsStream_->Init(this->fsHandle_);
}
AuSPtr<Loop::ILoopSource> IPCPipeImpl::AsReadChannelIsOpen()
@ -152,6 +155,11 @@ namespace Aurora::IO::IPC
return this->fsStream_->NewTransaction();
}
AuSPtr<IO::IIOHandle> IPCPipeImpl::GetCurrentSharedDuplexHandles()
{
return this->fsHandle_;
}
bool IPCPipeImpl::Read(const Memory::MemoryViewStreamWrite &write, bool nonblock)
{
auto handle = fds[0];

View File

@ -53,7 +53,8 @@ namespace Aurora::IO::IPC
#endif
virtual AuSPtr<IO::IAsyncTransaction> NewAsyncTransaction() override;
virtual AuSPtr<IO::IIOHandle> GetCurrentSharedDuplexHandles() override;
virtual AuSPtr<Loop::ILoopSource> AsReadChannelIsOpen() override;
virtual AuSPtr<Loop::ILoopSource> AsReadChannelHasData() override;
@ -84,7 +85,7 @@ namespace Aurora::IO::IPC
int fds[2] {-1, -1};
int secondary[2] {-1, -1};
AuSPtr<IO::FS::FileHandle> fsHandle_;
AuSPtr<IO::IIOHandle> fsHandle_;
AuSPtr<IO::FS::LinuxAsyncFileStream> fsStream_;
void SendTerminateSignal();

View File

@ -34,7 +34,16 @@ namespace Aurora::IO::Net
Socket::Socket(struct NetInterface *pInterface,
struct NetWorker *pWorker,
const AuSPtr<ISocketDriver> &pSocketDriver,
const NetEndpoint &endpoint) :
const AuPair<NetHostname, AuUInt16> &endpoint,
AuNet::ETransportProtocol eProtocol) :
SocketBase(pInterface, pWorker, pSocketDriver, endpoint, eProtocol)
{
}
Socket::Socket(struct NetInterface *pInterface,
struct NetWorker *pWorker,
const AuSPtr<ISocketDriver> &pSocketDriver,
const NetEndpoint &endpoint) :
SocketBase(pInterface, pWorker, pSocketDriver, endpoint)
{
}
@ -55,14 +64,48 @@ namespace Aurora::IO::Net
void Socket::CloseSocket()
{
if (this->osHandle_ &&
this->osHandle_ != -1)
this->osHandle_ = 0;
AuResetMember(this->osHandleOwner_);
}
void Socket::RenewSocket()
{
if (!this->SendPreestablish())
{
::close(this->osHandle_);
this->osHandle_ = 0;
SysPushErrorIO("Preestablish drop");
return;
}
if (this->bHasRemoteMany_ && this->connectMany_.ips.size())
{
this->remoteEndpoint_ = this->connectMany_.ips[0];
}
this->CloseSocket();
this->osHandle_ = ::socket(
IPToDomain(this->remoteEndpoint_),
TransportToPlatformType(this->remoteEndpoint_),
0
);
if (this->osHandle_ == -1)
{
this->SendErrorNoStream(GetLastNetError());
return;
}
this->osHandleOwner_ = AuIO::IOHandleShared();
this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_);
if (!this->PrepareConnectOperations())
{
this->bForceFailConstruct_ = true;
return;
}
}
void Socket::FinishConstructAsync()
{
if (!this->SendPreestablish())
@ -83,13 +126,13 @@ namespace Aurora::IO::Net
return;
}
this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_);
if (!this->PrepareConnectOperations())
{
this->bForceFailConstruct_ = true;
return;
}
this->osHandleOwner_->Init((int)this->osHandle_, (int)this->osHandle_);
}
bool Socket::PrepareConnectOperations()

View File

@ -29,6 +29,12 @@ namespace Aurora::IO::Net
const AuSPtr<ISocketDriver> &pSocketDriver,
AuUInt osHandle);
Socket(struct NetInterface *pInterface,
struct NetWorker *pWorker,
const AuSPtr<ISocketDriver> &pSocketDriver,
const AuPair<NetHostname, AuUInt16> &endpoint,
AuNet::ETransportProtocol eProtocol);
Socket(struct NetInterface *pInterface,
struct NetWorker *pWorker,
const AuSPtr<ISocketDriver> &pSocketDriver,
@ -61,6 +67,7 @@ namespace Aurora::IO::Net
virtual void Shutdown(bool bNow) override;
virtual void CloseSocket() override;
virtual void RenewSocket() override;
bool MakeCloseonexec();
};

View File

@ -113,6 +113,8 @@ namespace Aurora::IO::UNIX
{
static bool LinuxOverlappedSubmit(int fd, int op, AuUInt offset, ASubmittable *context, AuLoop::ILSEvent *optEvent);
static void IoTlsRedo();
//////////////////////////////////////////////////////////////////
// ASubmittable
//////////////////////////////////////////////////////////////////
@ -155,6 +157,8 @@ namespace Aurora::IO::UNIX
{
SysPushErrorCatch("IO Callback threw an exception");
}
IoTlsRedo();
}
UNIX::SendIOBuffers();
@ -274,6 +278,7 @@ namespace Aurora::IO::UNIX
aio_context_t context {};
AuList<iocb*> submitPendingArray;
AuUInt32 dwIoSubmits;
bool bPollHit {};
~TLSIO()
{
@ -298,6 +303,17 @@ namespace Aurora::IO::UNIX
return handle->bInitialized ? handle : nullptr;
}
void IoTlsRedo()
{
auto pTLS = GetTls();
if (!pTLS)
{
return;
}
pTLS->bPollHit = true;
}
//////////////////////////////////////////////////////////////////
// TLS IO IMPL
//////////////////////////////////////////////////////////////////
@ -594,7 +610,7 @@ namespace Aurora::IO::UNIX
}
}
} while (timeout);
} while (timeout || AuExchange(io->bPollHit, false));
return dwApcsSent;
}
@ -730,7 +746,7 @@ namespace Aurora::IO::UNIX
}
}
} while (timeout ? !bEpollTriggered : false);
} while ((timeout ? !bEpollTriggered : false) || AuExchange(io->bPollHit, false));
io_event finalEpollEvent {};
if ((bEpollTriggered) ||

View File

@ -39,7 +39,7 @@ namespace Aurora::Process
if (key.empty())
{
SysPushErrorArg("Missing key");
return false;
return {};
}
auto pValue = ::getenv(key.c_str());

View File

@ -156,7 +156,6 @@ namespace Aurora::Process
AuString file;
AuIOFS::GetFileFromPath(file, path);
auto object = AuIOFS::OpenReadUnique(path);
if (!object)
{
@ -169,6 +168,7 @@ namespace Aurora::Process
if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(&header, sizeof(header)), read)))
{
SysPushErrorIO();
continue;
}
AuList<Elf_Shdr> elfSections;
@ -188,10 +188,15 @@ namespace Aurora::Process
continue;
}
auto &strtab = elfSections[header.e_shstrndx];
AuList<AuUInt8> strHeap;
if (strtab.sh_size > 80 * 1024 * 1024)
{
SysPushErrorMem();
continue;
}
if (!AuTryResize(strHeap, strtab.sh_size))
{
SysPushErrorMem();
@ -211,6 +216,11 @@ namespace Aurora::Process
Sections modSections;
for (const auto & section : elfSections)
{
if (section.sh_name > strHeap.size())
{
continue;
}
auto len = strnlen((const char *)strHeap.data() + section.sh_name, strHeap.size() - section.sh_name);
AuString sectionName((const char *)strHeap.data() + section.sh_name, len);
AuUInt fileOffset = section.sh_offset;

View File

@ -95,7 +95,7 @@ namespace Aurora::Process
return false;
}
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength} });
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength_ } });
}
bool ProcessSectionFileMapView::UnlockSwap()
@ -105,6 +105,6 @@ namespace Aurora::Process
return false;
}
return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength} });
return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength_ } });
}
}

View File

@ -62,17 +62,16 @@ namespace Aurora::Process
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel sectionLock)
{
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
return file ? this->MapFileByObject(file, uOffset, uLength, mode, sectionLock) : AuSPtr<IProcessSectionMapView> {};
return this->MapFileByPathEx(0, str, uOffset, uLength, mode, sectionLock);
}
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObject(const AuSPtr<AuFS::IFileStream> &stream,
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 uOffset,
AuUInt uLength,
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel processLockLevel)
{
return this->MapFileByObjectEx(0, stream, uOffset, uLength, mode, processLockLevel);
return this->MapFileByObjectEx(0, pIOHandle, uOffset, uLength, mode, processLockLevel);
}
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapIPCMemory(const AuString &handleString,
@ -144,18 +143,37 @@ namespace Aurora::Process
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
{
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
return file ? this->MapFileByObjectEx(viewOffset, file, uOffset, uLength, mode, processLockLevel) : AuSPtr<IProcessSectionMapView> {};
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorMemory();
return nullptr;
}
AuIO::IIOHandle::HandleCreate createhandle(str);
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
createhandle.eMode = mode;
createhandle.bFailIfNonEmptyFile = false;
createhandle.bDirectIOMode = false;
createhandle.bAsyncHandle = false;
if (!pHandle->InitFromPath(createhandle))
{
return nullptr;
}
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel);
}
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObjectEx(AuUInt viewOffset,
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
{
if (!pStream)
if (!pIOHandle)
{
return {};
}
@ -166,8 +184,7 @@ namespace Aurora::Process
return {};
}
auto ok = AuStaticCast<AuFS::PosixFileStream>(pStream);
int fd = ::dup(ok->GetHandle());
int fd = ::dup(pIOHandle->GetOSHandle());
if (fd == -1)
{
SysPushErrorIO();

View File

@ -23,7 +23,7 @@ namespace Aurora::Process
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel sectionLock) override;
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<Aurora::IO::FS::IFileStream> &stream,
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 offset,
AuUInt length,
Aurora::IO::FS::EFileOpenMode mode,
@ -46,7 +46,7 @@ namespace Aurora::Process
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) override;
AuSPtr<IProcessSectionMapView> MapFileByObjectEx(AuUInt viewOffset,
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,

View File

@ -89,22 +89,21 @@ namespace Aurora::Process
}
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByPath(const AuString &str,
AuUInt64 uOffset,
AuUInt uLength,
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel sectionLock)
AuUInt64 uOffset,
AuUInt uLength,
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel sectionLock)
{
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
return file ? this->MapFileByObject(file, uOffset, uLength, mode, sectionLock) : AuSPtr<IProcessSectionMapView> {};
return this->MapFileByPathEx(-1, str, uOffset, uLength, mode, sectionLock);
}
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObject(const AuSPtr<AuFS::IFileStream> &stream,
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 uOffset,
AuUInt uLength,
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel processLockLevel)
{
return this->MapFileByObjectEx(-1, stream, uOffset, uLength, mode, processLockLevel);
return this->MapFileByObjectEx(-1, pIOHandle, uOffset, uLength, mode, processLockLevel);
}
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapIPCMemory(const AuString &handleString,
@ -170,24 +169,42 @@ namespace Aurora::Process
}
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByPathEx(AuUInt viewOffset,
const AuString &str,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
const AuString &str,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
{
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
return file ? this->MapFileByObjectEx(viewOffset, file, uOffset, uLength, mode, processLockLevel) : AuSPtr<IProcessSectionMapView> {};
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorMemory();
return nullptr;
}
AuIO::IIOHandle::HandleCreate createhandle(str);
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
createhandle.eMode = mode;
createhandle.bFailIfNonEmptyFile = false;
createhandle.bDirectIOMode = false;
createhandle.bAsyncHandle = false;
if (!pHandle->InitFromPath(createhandle))
{
return nullptr;
}
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel);
}
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObjectEx(AuUInt viewOffset,
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
{
if (!pStream)
if (!pIOHandle)
{
return {};
}
@ -204,8 +221,7 @@ namespace Aurora::Process
return {};
}
auto ok = AuStaticCast<AuFS::PosixFileStream>(pStream);
int fd = ::dup(ok->GetHandle());
int fd = ::dup(pIOHandle->GetOSHandle());
if (fd == -1)
{
SysPushErrorIO();

View File

@ -30,7 +30,7 @@ namespace Aurora::Process
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel sectionLock) override;
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<Aurora::IO::FS::IFileStream> &stream,
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 offset,
AuUInt length,
Aurora::IO::FS::EFileOpenMode mode,
@ -53,7 +53,7 @@ namespace Aurora::Process
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) override;
AuSPtr<IProcessSectionMapView> MapFileByObjectEx(AuUInt viewOffset,
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
const AuSPtr<IO::IIOHandle> &pIOHandle,
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,

View File

@ -154,7 +154,7 @@ namespace Aurora::Processes
{
if (::kill(this->pidt_, SIGTERM) == 0)
{
return this->finished_->Lock(500);
return this->finished_->LockMS(500);
}
}
@ -283,6 +283,9 @@ namespace Aurora::Processes
fds[0] = ::open("/dev/null", O_RDWR);
fds[1] = ::open("/dev/null", O_RDWR);
break;
case EStreamForward::eNewConsoleWindow:
SysPushErrorGeneric("AuProcesses is not the right place for PTY support. At least not in this form (this level of abstraction only cares for pipes).");
break;
}
return true;
@ -310,7 +313,7 @@ namespace Aurora::Processes
if ((this->startup_.fwdIn == EStreamForward::eAsyncPipe) ||
(this->startup_.fwdOut == EStreamForward::eAsyncPipe))
{
this->fsHandle_ = AuMakeShared<IO::FS::FileHandle>();
this->fsHandle_ = AuIO::IOHandleShared();
if (!this->fsHandle_)
{
return false;
@ -322,13 +325,13 @@ namespace Aurora::Processes
return false;
}
this->fsHandle_->Init(this->pipeStdOut_[0], this->pipeStdIn_[1]);
this->fsHandle_->InitFromPairMove(this->pipeStdOut_[0], this->pipeStdIn_[1]);
this->fsStream_->Init(this->fsHandle_);
}
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
{
this->fsErrorHandle_ = AuMakeShared<IO::FS::FileHandle>();
this->fsErrorHandle_ = AuIO::IOHandleShared();
if (!this->fsErrorHandle_)
{
return false;
@ -340,7 +343,7 @@ namespace Aurora::Processes
return false;
}
this->fsErrorHandle_->Init(this->pipeStdErr_[0], -1);
this->fsErrorHandle_->InitFromPairMove(this->pipeStdErr_[0], -1);
this->fsErrorStream_->Init(this->fsErrorHandle_);
}

View File

@ -66,10 +66,10 @@ namespace Aurora::Processes
AuSPtr<IO::Loop::ILSEvent> loopSource_;
AuSPtr<IO::FS::FileHandle> fsHandle_;
AuSPtr<IO::IIOHandle> fsHandle_;
AuSPtr<ProcessPipeFileStream> fsStream_;
AuSPtr<IO::FS::FileHandle> fsErrorHandle_;
AuSPtr<IO::IIOHandle> fsErrorHandle_;
AuSPtr<ProcessPipeFileStream> fsErrorStream_;
AuThreadPrimitives::EventShared_t finished_;

View File

@ -175,7 +175,7 @@ namespace Aurora::RNG
acc = a = b = c = 0;
bits = 8;
void *pASLRSeed = &RngTimeBased;
void *pASLRSeed = (void *)&RngTimeBased;
for (AU_ITERATE_N(uOffsetInByteStream, uLen))
{

View File

@ -13,6 +13,12 @@
#include <timeapi.h>
#endif
#if defined(AURORA_IS_LINUX_DERIVED)
#include <linux/futex.h>
#include <sys/syscall.h>
#include <unistd.h>
#endif
#include <Time/Time.hpp>
#define HACK_NO_INVALID_ACCESS_LEAK_SHARED_REF_ON_DESTROYED_THREAD
@ -27,6 +33,13 @@ namespace Aurora::Threading
#endif
#if defined(AURORA_IS_LINUX_DERIVED)
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
const struct timespec *timeout,
uint32_t *uaddr2, uint32_t val3)
{
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
{
if (timeout)
@ -466,17 +479,17 @@ namespace Aurora::Threading
static bool RunOSWaitOnAddressNoTimed(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 dwWordSize)
AuUInt8 uWordSize)
{
#if defined(AURORA_IS_MODERNNT_DERIVED)
return pWaitOnAddress((void *)pTargetAddress, (void *)pCompareAddress, dwWordSize, INFINITE);
return pWaitOnAddress((void *)pTargetAddress, (void *)pCompareAddress, uWordSize, INFINITE);
#endif
#if defined(AURORA_IS_LINUX_DERIVED)
int ret {};
#if defined(AU_CPU_ENDIAN_BIG)
if (dwWordSize == 8)
if (uWordSize == 8)
{
pTargetAddress = AuReinterpretCast<const char *>(pTargetAddress) + 4;
pCompareAddress = AuReinterpretCast<const char *>(pCompareAddress) + 4;
@ -679,7 +692,7 @@ namespace Aurora::Threading
auto uCurrent = *(AuUInt32 *)pCompareAddress;
struct timespec tspec;
Time::auabsns2ts(&tspec, uAbsTimeAltClock ? uAbsTimeAltClock.value() : uAbsTimeSteadyClock);
Time::monoabsns2ts(&tspec, uAbsTimeAltClock ? uAbsTimeAltClock.value() : uAbsTimeSteadyClock);
do
{

View File

@ -13,7 +13,8 @@
namespace Aurora::Threading::Primitives
{
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex) : mutex_(std::dynamic_pointer_cast<IConditionMutexEx>(mutex))
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &pMutex) :
mutex_(AuStaticCast<UnixConditionMutex>(pMutex))
{
pthread_condattr_t attr;
@ -41,14 +42,20 @@ namespace Aurora::Threading::Primitives
bool ConditionVariableImpl::WaitForSignalNS(AuUInt64 qwTimeout)
{
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_->GetOSHandle());
return WaitForSignalNsEx(this->mutex_, qwTimeout);
}
bool ConditionVariableImpl::WaitForSignalNsEx(const std::shared_ptr<UnixConditionMutex> &pMutex,
AuUInt64 qwTimeout)
{
auto mutex = reinterpret_cast<pthread_mutex_t*>(pMutex->GetOSHandle());
if (gRuntimeRunLevel >= 5)
{
return true;
}
if (timeout == 0)
if (qwTimeout == 0)
{
int ret {};
do
@ -65,7 +72,7 @@ namespace Aurora::Threading::Primitives
else
{
struct timespec tspec;
Time::auabsns2ts(&tspec, AuTime::CurrentClockNS() + qwTimeout);
Time::monoabsns2ts(&tspec, AuTime::SteadyClockNS() + qwTimeout);
int ret {};

View File

@ -8,23 +8,33 @@
#pragma once
#if !defined(_AURUNTIME_GENERICCV)
#include "AuConditionMutex.Unix.hpp"
namespace Aurora::Threading::Primitives
{
struct ConditionVariableImpl : IConditionVariable
struct ConditionVariableImpl final : IConditionVariable
{
ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex);
~ConditionVariableImpl();
AuSPtr<IConditionMutex> GetMutex() override;
bool WaitForSignal(AuUInt32 timeout) override;
bool WaitForSignalNS(AuUInt64 timeout) override;
bool WaitForSignalNsEx(const std::shared_ptr<UnixConditionMutex> &pMutex, AuUInt64 timeout);
bool WaitForSignalNS(AuUInt64 qwTimeout) override;
void Signal() override;
void Broadcast() override;
// TODO: ...
pthread_cond_t pthreadCv_;
private:
AuSPtr<IConditionMutexEx> mutex_;
AuSPtr<UnixConditionMutex> mutex_;
};
struct CondVarDummy : IConditionVariable
{
pthread_cond_t pthreadCv_;
};
static const auto kSizeOfDummyCondVar = sizeof(CondVarDummy);
}
#endif

View File

@ -17,6 +17,9 @@
namespace Aurora::Threading::Primitives
{
#define barrier() __asm__ __volatile__("sfence": : :"memory")
#define compilerReorderBarrier() __asm__ __volatile__("": : :"memory")
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
const struct timespec *timeout,
uint32_t *uaddr2, uint32_t val3)
@ -24,26 +27,26 @@ namespace Aurora::Threading::Primitives
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}
static int futex_wait(uint32_t *addr, uint32_t expected)
static int futex_wait(volatile uint32_t *addr, uint32_t expected)
{
return futex(addr, FUTEX_WAIT, expected, 0, 0, 0);
return futex((uint32_t *)addr, FUTEX_WAIT, expected, 0, 0, 0);
}
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
static int futex_wait(volatile uint32_t *addr, uint32_t expected, const struct timespec *timeout)
{
if (timeout)
{
return futex(addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
return futex((uint32_t *)addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
}
else
{
return futex(addr, FUTEX_WAIT, expected, timeout, 0, 0);
return futex((uint32_t *)addr, FUTEX_WAIT, expected, timeout, 0, 0);
}
}
static int futex_wake(uint32_t *addr, uint32_t nthreads)
static int futex_wake(volatile uint32_t *addr, uint32_t nthreads)
{
return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0);
return futex((uint32_t *)addr, FUTEX_WAKE, nthreads, 0, 0, 0);
}
MutexImpl::MutexImpl()
@ -70,8 +73,7 @@ namespace Aurora::Threading::Primitives
{
return DoTryIf([=]()
{
auto old = this->value_;
return (old == 0 && AuAtomicCompareExchange<AuUInt32>(&this->value_, 1, old) == old);
return AuAtomicTestAndSet(&this->state_, 0) == 0;
});
}
@ -90,29 +92,36 @@ namespace Aurora::Threading::Primitives
return true;
}
AuAtomicAdd(&this->dwSleeping_, 1u);
//redundant: 8.2.3.8
//barrier();
struct timespec tspec;
if (uTimeout != 0)
{
uStart = AuTime::SteadyClockNS();
uEnd = uStart + uTimeout;
Time::auabsns2ts(&tspec, uEnd);
Time::monoabsns2ts(&tspec, uEnd);
}
auto state = this->value_;
while (!(state == 0 && AuAtomicCompareExchange<AuUInt32>(&this->value_, 1, state) == state))
auto state = this->state_;
while (!(state == 0 &&
AuAtomicCompareExchange<AuUInt32>(&this->state_, 1, state) == state))
{
if (uTimeout != 0)
{
if (Time::SteadyClockNS() >= uEnd)
{
AuAtomicSub(&this->dwSleeping_, 1u);
return false;
}
int ret {};
do
{
ret = futex_wait(&this->value_, state, &tspec);
ret = futex_wait(&this->state_, state, &tspec);
}
while (ret == EINTR);
}
@ -123,7 +132,7 @@ namespace Aurora::Threading::Primitives
do
{
if ((ret = futex_wait(&this->value_, state)) == 0)
if ((ret = futex_wait(&this->state_, state)) == 0)
{
bStatus = true;
break;
@ -141,13 +150,14 @@ namespace Aurora::Threading::Primitives
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
}
state = this->value_;
state = this->state_;
}
AuAtomicSub(&this->dwSleeping_, 1u);
return true;
}
void MutexImpl::Lock()
void MutexImpl::SlowLock()
{
auto status = LockMS(0);
SysAssert(status, "Couldn't lock mutex");
@ -155,16 +165,20 @@ namespace Aurora::Threading::Primitives
void MutexImpl::Unlock()
{
this->value_ = 0;
futex_wake(&this->value_, 1);
__sync_lock_release(&this->state_);
compilerReorderBarrier();
if (this->dwSleeping_)
{
futex_wake(&this->state_, 1);
}
}
AUKN_SYM IWaitable *MutexNew()
AUKN_SYM IHyperWaitable *MutexNew()
{
return _new MutexImpl();
}
AUKN_SYM void MutexRelease(IWaitable *pMutex)
AUKN_SYM void MutexRelease(IHyperWaitable *pMutex)
{
AuSafeDelete<MutexImpl *>(pMutex);
}

View File

@ -9,7 +9,7 @@
namespace Aurora::Threading::Primitives
{
struct MutexImpl : IWaitable
struct MutexImpl : IHyperWaitable
{
MutexImpl();
~MutexImpl();
@ -17,12 +17,11 @@ namespace Aurora::Threading::Primitives
bool HasOSHandle(AuMach &mach) override;
bool TryLock() override;
bool HasLockImplementation() override;
void Lock() override;
void SlowLock() override;
bool LockMS(AuUInt64 timeout) override;
bool LockNS(AuUInt64 timeout) override;
void Unlock() override;
private:
AuUInt32 value_ {};
AuUInt32 dwSleeping_ {};
};
}

View File

@ -14,6 +14,9 @@
namespace Aurora::Threading::Primitives
{
#define barrier() __asm__ __volatile__("sfence": : :"memory")
#define compilerReorderBarrier() __asm__ __volatile__("": : :"memory")
MutexImpl::MutexImpl()
{
pthread_condattr_t attr;
@ -68,6 +71,8 @@ namespace Aurora::Threading::Primitives
return true;
}
AuAtomicAdd(&this->dwSleeping_, 1u);
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_.GetOSHandle());
struct timespec tspec;
@ -76,7 +81,7 @@ namespace Aurora::Threading::Primitives
uStart = AuTime::SteadyClockNS();
uEnd = uStart + uTimeout;
Time::auabsns2ts(&tspec, uEnd);
Time::monoabsns2ts(&tspec, uEnd);
}
int ret {};
@ -93,6 +98,7 @@ namespace Aurora::Threading::Primitives
{
if (Time::SteadyClockNS() >= uEnd)
{
AuAtomicSub(&this->dwSleeping_, 1u);
return false;
}
@ -120,6 +126,7 @@ namespace Aurora::Threading::Primitives
}
}
AuAtomicSub(&this->dwSleeping_, 1u);
return true;
}
@ -131,12 +138,20 @@ namespace Aurora::Threading::Primitives
void MutexImpl::Unlock()
{
__sync_lock_release(&this->value_);
compilerReorderBarrier();
if (this->dwSleeping_)
{
AU_LOCK_GUARD(this->mutex_);
this->value_ = 0;
{
// Still required to barrier the mutually exclusive part of the condvar
AU_LOCK_GUARD(this->mutex_);
//this->value_ = 0;
}
auto ret = ::pthread_cond_signal(&this->pthreadCv_);
SysAssert(ret == 0, "Couldn't wake any mutex waiter");
}
auto ret = ::pthread_cond_signal(&this->pthreadCv_);
SysAssert(ret == 0, "Couldn't wake any mutex waiter");
}
AUKN_SYM IWaitable *MutexNew()

View File

@ -26,8 +26,8 @@ namespace Aurora::Threading::Primitives
auline bool TryLockNoSpin();
private:
AuInt32 value_ {};
pthread_cond_t pthreadCv_ {};
UnixConditionMutex mutex_;
AuUInt32 dwSleeping_ {};
};
}

View File

@ -97,7 +97,7 @@ namespace Aurora::Threading::Primitives
uStart = AuTime::SteadyClockNS();
uEnd = uStart + uTimeout;
Time::auabsns2ts(&tspec, uEnd);
Time::monoabsns2ts(&tspec, uEnd);
}
auto old = this->value_;

View File

@ -78,7 +78,7 @@ namespace Aurora::Threading::Primitives
uStart = AuTime::SteadyClockNS();
uEnd = uStart + uTimeout;
Time::auabsns2ts(&tspec, uEnd);
Time::monoabsns2ts(&tspec, uEnd);
}
while (!this->TryLock())

View File

@ -457,9 +457,11 @@ namespace Aurora::Threading::Threads
auto ret = SpawnThread([this]()
{
while ((!this->handle_) ||
#if defined(INVALID_HANDLE_VALUE)
#if defined(INVALID_HANDLE_VALUE)
(this->handle_ == INVALID_HANDLE_VALUE)
#endif
#else
0
#endif
)
{
AuThreading::ContextYield();
@ -693,6 +695,11 @@ namespace Aurora::Threading::Threads
#elif defined(AURORA_HAS_PTHREADS)
if (!this->handle_)
{
return;
}
pthread_setname_np(this->handle_, this->name_.c_str());
#endif
@ -1022,7 +1029,12 @@ namespace Aurora::Threading::Threads
return;
#elif defined(AURORA_HAS_PTHREADS)
if (!this->handle_)
{
return;
}
auto mask2 = mask.And(this->throttleMask_);
if (mask2.CpuBitCount() == 0)

View File

@ -63,6 +63,10 @@ using high_res_clock = std::chrono::high_resolution_clock;
#endif
#if defined(AURORA_IS_POSIX_DERIVED)
#include <sys/resource.h>
#endif
using sys_clock = std::chrono::system_clock;
using steady_clock = std::chrono::steady_clock;

View File

@ -84,12 +84,19 @@ namespace Aurora::Time
ts->tv_nsec = remainderNS;
}
static void monoabsns2ts(struct timespec *ts, unsigned long long ns)
{
auto remainderNS = (AuUInt64)ns % (AuUInt64)1'000'000'000;
ts->tv_sec = ns / 1'000'000'000ull;
ts->tv_nsec = remainderNS;
}
static void auabsns2ts(struct timespec *ts, unsigned long long ns)
{
auto baseNS = ns + AuMSToNS<AuUInt64>(999'080'100'000);
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
ts->tv_sec += baseNS / 1'000'000'000ull;
ts->tv_sec = baseNS / 1'000'000'000ull;
ts->tv_nsec = remainderNS;
}