[*] Linux: Harden recursive IO scheduling

This commit is contained in:
Reece Wilson 2024-08-05 19:44:54 +01:00
parent 55cac676f5
commit 57c5515173
2 changed files with 52 additions and 41 deletions

View File

@ -261,6 +261,7 @@ namespace Aurora
struct IOConfig struct IOConfig
{ {
AuUInt32 uProtocolStackDefaultBufferSize { 64 * 1024 }; AuUInt32 uProtocolStackDefaultBufferSize { 64 * 1024 };
bool bIsVeryLargeIOApplication { false };
}; };
struct Win32Config struct Win32Config

View File

@ -158,39 +158,7 @@ namespace Aurora::IO::UNIX
int ASubmittable::GetOrCreateFdPollForBlockingRead(int fd) int ASubmittable::GetOrCreateFdPollForBlockingRead(int fd)
{ {
#if 1 return fd;
return fd; // wtf freetards are incapable of writing an os.
// the indirection of fds read state wasn't the problem.
// linux will never be a real kernel
// gnu will never be a real operating system
#else
// TODO (Reece): urgent: is this hack overkill? can we
// just return fd?
if ((this->tempEPoll == 0) ||
(this->tempEPoll == -1))
{
epoll_event event;
if ((this->tempEPoll = ::epoll_create1(0)) == -1)
{
SysPushErrorIO();
return -1;
}
event.events = EPOLLIN;
event.data.ptr = nullptr;
if (::epoll_ctl(this->tempEPoll, EPOLL_CTL_ADD, fd, &event) != 0)
{
SysPushErrorIO();
::close(this->tempEPoll);
this->tempEPoll = -1;
return -1;
}
}
return this->tempEPoll;
#endif
} }
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -244,11 +212,21 @@ namespace Aurora::IO::UNIX
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
bool TLSIO::Init() bool TLSIO::Init()
{
if (gRuntimeConfig.ioConfig.bIsVeryLargeIOApplication)
{
if (io_setup(1024 * 256, &this->context) != 0)
{
return false;
}
}
else
{ {
if (io_setup(1024, &this->context) != 0) if (io_setup(1024, &this->context) != 0)
{ {
return false; return false;
} }
}
return true; return true;
} }
@ -740,7 +718,9 @@ namespace Aurora::IO::UNIX
} }
bool bEpollTriggered {}; bool bEpollTriggered {};
io_event ioEvents[512]; io_event ioEvents[1024];
AuTuple<ASubmittable *, AuUInt, bool, int> toProcess[1024] {};
int toProcessDone {};
int temp {}; int temp {};
bool bAgain {}; bool bAgain {};
@ -758,7 +738,12 @@ namespace Aurora::IO::UNIX
AuTime::ns2ts(&targetTime, uTimeNow - uTargetTime); AuTime::ns2ts(&targetTime, uTimeNow - uTargetTime);
} }
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr); auto uCount = AuMin(AuArraySize(ioEvents), AuArraySize(toProcess) - toProcessDone);
if (uCount == 0)
{
break;
}
temp = io_getevents(io->context, 1, uCount, ioEvents, timeout ? &targetTime : nullptr);
if (temp >= 0) if (temp >= 0)
{ {
@ -782,7 +767,7 @@ namespace Aurora::IO::UNIX
bytesTransacted = ioEvents[i].res; bytesTransacted = ioEvents[i].res;
} }
handle->LIOS_SendProcess(bytesTransacted, bError, errNo); toProcess[toProcessDone++] = AuMakeTuple(handle, bytesTransacted, bError, errNo);
} }
else else
{ {
@ -844,6 +829,15 @@ namespace Aurora::IO::UNIX
} }
} }
for (AU_ITERATE_N(i, toProcessDone))
{
auto handle = AuGet<0>(toProcess[i]);
auto bytesTransacted = AuGet<1>(toProcess[i]);
auto bError = AuGet<2>(toProcess[i]);
auto errNo = AuGet<3>(toProcess[i]);
handle->LIOS_SendProcess(bytesTransacted, bError, errNo);
}
if (bEpollTriggered) if (bEpollTriggered)
{ {
return epoll_wait(epfd, events, maxevents, 0); return epoll_wait(epfd, events, maxevents, 0);
@ -939,7 +933,9 @@ namespace Aurora::IO::UNIX
return -1; return -1;
} }
io_event ioEvents[512]; io_event ioEvents[1024];
AuTuple<ASubmittable *, AuUInt, bool, int> toProcess[1024] {};
int toProcessDone {};
int temp; int temp;
do do
@ -956,7 +952,12 @@ namespace Aurora::IO::UNIX
AuTime::ns2ts(&targetTime, uTimeNow - uTargetTime); AuTime::ns2ts(&targetTime, uTimeNow - uTargetTime);
} }
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr); auto uCount = AuMin(AuArraySize(ioEvents), AuArraySize(toProcess) - toProcessDone);
if (uCount == 0)
{
break;
}
temp = io_getevents(io->context, 1, uCount, ioEvents, timeout ? &targetTime : nullptr);
if (temp >= 0) if (temp >= 0)
{ {
@ -994,7 +995,7 @@ namespace Aurora::IO::UNIX
bytesTransacted = ioEvents[i].res; bytesTransacted = ioEvents[i].res;
} }
handle->LIOS_SendProcess(bytesTransacted, bError, errNo); toProcess[toProcessDone++] = AuMakeTuple(handle, bytesTransacted, bError, errNo);
} }
} }
} }
@ -1061,6 +1062,15 @@ namespace Aurora::IO::UNIX
} }
} }
for (AU_ITERATE_N(i, toProcessDone))
{
auto handle = AuGet<0>(toProcess[i]);
auto bytesTransacted = AuGet<1>(toProcess[i]);
auto bError = AuGet<2>(toProcess[i]);
auto errNo = AuGet<3>(toProcess[i]);
handle->LIOS_SendProcess(bytesTransacted, bError, errNo);
}
return bRet; return bRet;
} }