Skip to content

Commit

Permalink
Precision sleep implementation for Linux (nanosleep).
Browse files Browse the repository at this point in the history
  • Loading branch information
PJB3005 committed Jul 15, 2023
1 parent d80be16 commit 0a5a214
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions Robust.Shared/Timing/PrecisionSleep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public static PrecisionSleep Create()
if (OperatingSystem.IsWindows() && Environment.OSVersion.Version.Build >= 17134)
return new PrecisionSleepWindowsHighResolution();

if (OperatingSystem.IsLinux())
return new PrecisionSleepLinuxNanosleep();

return new PrecisionSleepUniversal();
}

Expand Down Expand Up @@ -108,3 +111,45 @@ public override void Dispose()
DisposeCore();
}
}

/// <summary>
/// High-precision implementation of <see cref="PrecisionSleep"/> that is available on Linux.
/// </summary>
internal sealed unsafe class PrecisionSleepLinuxNanosleep : PrecisionSleep
{
public override void Sleep(TimeSpan time)
{
timespec timeSpec;
timeSpec.tv_sec = Math.DivRem(time.Ticks, TimeSpan.TicksPerSecond, out var ticksRem);
timeSpec.tv_nsec = ticksRem * TimeSpan.NanosecondsPerTick;

while (true)
{
timespec rem;
var result = nanosleep(&timeSpec, &rem);
if (result == 0)
return;

var error = Marshal.GetLastSystemError();
if (error != 4) // EINTR
throw new Exception($"nanosleep failed: {error}");

timeSpec = rem;
}
}

[DllImport("libc.so.6", SetLastError=true)]
private static extern int nanosleep(timespec* req, timespec* rem);

private struct timespec

Check warning on line 144 in Robust.Shared/Timing/PrecisionSleep.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The type name 'timespec' only contains lower-cased ascii characters. Such names may become reserved for the language.

Check warning on line 144 in Robust.Shared/Timing/PrecisionSleep.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

The type name 'timespec' only contains lower-cased ascii characters. Such names may become reserved for the language.

Check warning on line 144 in Robust.Shared/Timing/PrecisionSleep.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

The type name 'timespec' only contains lower-cased ascii characters. Such names may become reserved for the language.
{
public long tv_sec;
public long tv_nsec;
}

private struct timeval

Check warning on line 150 in Robust.Shared/Timing/PrecisionSleep.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The type name 'timeval' only contains lower-cased ascii characters. Such names may become reserved for the language.

Check warning on line 150 in Robust.Shared/Timing/PrecisionSleep.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

The type name 'timeval' only contains lower-cased ascii characters. Such names may become reserved for the language.

Check warning on line 150 in Robust.Shared/Timing/PrecisionSleep.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

The type name 'timeval' only contains lower-cased ascii characters. Such names may become reserved for the language.
{
public long tv_sec;
public long tv_usec;
}
}

0 comments on commit 0a5a214

Please sign in to comment.