I wrote a piece of code that runs fine on Windows, but instead of sleeping, it continues to execute on Linux.
if (FParse::Param(*Params, TEXT("NoClient")))
{
FPlatformProcess::Sleep(1000000);
}
I checked that the command line parameters were correct, after checked the document, I changed it to call SleepInfinite
and it worked.
The problem is solved, but why doesn’t it work under Linux? I found the source code for Linux:
Engine\Source\Runtime\Core\Public\Linux\LinuxPlatformProcess.h:
struct CORE_API FLinuxPlatformProcess : public FUnixPlatformProcess
{
...
};
typedef FLinuxPlatformProcess FPlatformProcess;
Engine\Source\Runtime\Core\Public\Unix\UnixPlatformProcess.h:
struct CORE_API FUnixPlatformProcess : public FGenericPlatformProcess
Engine\Source\Runtime\Core\Private\GenericPlatform\GenericPlatformProcess.cpp:
void FGenericPlatformProcess::SleepNoStats( float Seconds )
{
const int32 usec = FPlatformMath::TruncToInt(Seconds * 1000000.0f);
if (usec > 0)
{
usleep(usec);
}
else
{
sched_yield();
}
}
The obvious reason is that the usec
variable overflowed the int32 limit.
(gdb) p (int)(1000000 * 1000000)
1 = -727379968
And looking at sleep(), even if it’s not overflowed, the usec
argument can’t exceed 1000000, which is one second.
EINVAL usec is greater than or equal to 1000000. (On systems where that is considered an error.)
And usleep
is deprecated, we suggest using nanosleep instead.
The UE documentation doesn’t mention this at all, it just says:
Sleep this thread for Seconds. 0.0 means release the current time slice to let other threads get some attention. uses stats.
How to fix it: using nanosleep
to implement it.