[*] Linux: fix spinning in an io_submit=EAGAIN loop

This commit is contained in:
Reece Wilson 2024-08-05 04:32:52 +01:00
parent 5947e6a2c3
commit 75f6325ee2
2 changed files with 54 additions and 5 deletions

View File

@ -609,6 +609,10 @@ namespace Aurora::IO::FS
}
else
{
if (!this->pCompletionGroup_ && !this->loopSource_)
{
this->loopSource_ = AuMakeShared<LinuxAsyncFileTransactionLoopSource>(AuSharedFromThis());
}
return AuStaticCast<Loop::ILoopSource>(AuStaticCast<Loop::ILSEvent>(this->loopSource_));
}
}

View File

@ -263,6 +263,14 @@ namespace Aurora::IO::UNIX
// GLUE
//////////////////////////////////////////////////////////////////
static void HandleEAGAIN()
{
// DO NOT
LinuxOverlappedYield();
// CHANGE!
sched_yield();
}
static bool LinuxOverlappedTrySubmitWorkInternal(TLSIO *io)
{
int index {};
@ -270,7 +278,16 @@ namespace Aurora::IO::UNIX
while (index != startingLength)
{
int ret = io_submit(io->context, io->submitPendingArray.size() - index, io->submitPendingArray.data() + index);
int ret;
do
{
ret = io_submit(io->context, io->submitPendingArray.size() - index, io->submitPendingArray.data() + index);
if (ret == -EAGAIN)
{
HandleEAGAIN();
}
}
while (ret == -EAGAIN);
if (ret <= 0)
{
@ -377,6 +394,7 @@ namespace Aurora::IO::UNIX
context->abortContext = io->context;
iocb &submit = context->GetIOCB();
AuMemset(&submit, 0, sizeof(submit));
submit.aio_data = context->GetData();
submit.aio_lio_opcode = op;
submit.aio_reqprio = 0;
@ -694,6 +712,7 @@ namespace Aurora::IO::UNIX
// evil nested epoll garbage
// but i'm sure the kevent way would be more inefficient
iocb pollSubmit {};
AuMemset(&pollSubmit, 0, sizeof(pollSubmit));
pollSubmit.aio_fildes = epfd;
pollSubmit.aio_lio_opcode = IOCB_CMD_POLL;
pollSubmit.aio_buf = POLLIN;
@ -701,9 +720,21 @@ namespace Aurora::IO::UNIX
iocb * ptr = &pollSubmit;
iocb ** ptrArray = &ptr;
if (io_submit(io->context, 1, ptrArray) <= 0)
errno = 0;
int error;
do
{
error = io_submit(io->context, 1, ptrArray);
if (error == -EAGAIN)
{
HandleEAGAIN();
}
}
while (error == -EAGAIN);
if (error <= 0)
{
errno = EFAULT;
SysPushErrorIO();
return -1;
}
@ -797,7 +828,7 @@ namespace Aurora::IO::UNIX
io_event finalEpollEvent {};
if (!bEpollTriggered)
{
if (io_cancel(io->context, ptr, &finalEpollEvent) != 0)
if (io_cancel(io->context, &pollSubmit, &finalEpollEvent) != 0)
{
if (errno != EINPROGRESS)
{
@ -864,6 +895,9 @@ namespace Aurora::IO::UNIX
iocb submit {};
iocb readSubmit {};
iocb writeSubmit {};
AuMemset(&readSubmit, 0, sizeof(readSubmit));
AuMemset(&writeSubmit, 0, sizeof(readSubmit));
AuMemset(&submit, 0, sizeof(submit));
submit.aio_lio_opcode = IOCB_CMD_POLL;
iocb * ptrArray[2];
@ -887,7 +921,18 @@ namespace Aurora::IO::UNIX
ptrArray[iocbIdx++] = &writeSubmit;
}
if (io_submit(io->context, iocbIdx, ptrArray) <= 0)
int error;
do
{
error = io_submit(io->context, iocbIdx, ptrArray);
if (error == -EAGAIN)
{
HandleEAGAIN();
}
}
while (error == -EAGAIN);
if (error <= 0)
{
errno = EFAULT;
SysPushErrorIO();