Initial commit

This commit is contained in:
2026-07-13 09:25:40 +07:00
parent c08ff54676
commit bccfb156d7
1938 changed files with 641646 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
using System;
using System.Runtime.InteropServices;
namespace RobotNet10.Realtime;
/// <summary>
/// Provides memory locking functionality for real-time applications.
/// Prevents memory from being swapped to disk, ensuring deterministic access times.
/// </summary>
public static class MemoryLock
{
/// <summary>
/// Locks a specific memory region to prevent swapping.
/// </summary>
/// <param name="address">Pointer to the memory region</param>
/// <param name="length">Length of the memory region in bytes</param>
/// <exception cref="InvalidOperationException">Thrown when the operation fails.</exception>
public static void Lock(IntPtr address, IntPtr length)
{
int result = LinuxNative.mlock(address, length);
if (result != 0)
{
LinuxNative.ThrowLastError("mlock");
}
}
/// <summary>
/// Unlocks a specific memory region.
/// </summary>
/// <param name="address">Pointer to the memory region</param>
/// <param name="length">Length of the memory region in bytes</param>
/// <exception cref="InvalidOperationException">Thrown when the operation fails.</exception>
public static void Unlock(IntPtr address, IntPtr length)
{
int result = LinuxNative.munlock(address, length);
if (result != 0)
{
LinuxNative.ThrowLastError("munlock");
}
}
/// <summary>
/// Locks all current and future memory pages for the process.
/// </summary>
/// <param name="flags">Lock flags (MCL_CURRENT, MCL_FUTURE, MCL_ONFAULT)</param>
/// <exception cref="InvalidOperationException">Thrown when the operation fails.</exception>
public static void LockAll(MemoryLockFlags flags)
{
int result = LinuxNative.mlockall((int)flags);
if (result != 0)
{
LinuxNative.ThrowLastError("mlockall");
}
}
/// <summary>
/// Unlocks all memory pages for the process.
/// </summary>
/// <exception cref="InvalidOperationException">Thrown when the operation fails.</exception>
public static void UnlockAll()
{
int result = LinuxNative.munlockall();
if (result != 0)
{
LinuxNative.ThrowLastError("munlockall");
}
}
/// <summary>
/// Locks a managed array to prevent swapping.
/// </summary>
/// <typeparam name="T">Type of array elements</typeparam>
/// <param name="array">Array to lock</param>
/// <returns>GCHandle that must be kept alive while the memory is locked</returns>
public static GCHandle LockArray<T>(T[] array)
{
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
IntPtr address = handle.AddrOfPinnedObject();
IntPtr length = new IntPtr(Marshal.SizeOf<T>() * array.Length);
Lock(address, length);
}
catch
{
handle.Free();
throw;
}
return handle;
}
}
/// <summary>
/// Memory locking flags.
/// </summary>
[Flags]
public enum MemoryLockFlags
{
/// <summary>
/// Lock all pages currently mapped into the address space of the process.
/// </summary>
Current = LinuxNative.MCL_CURRENT,
/// <summary>
/// Lock all pages that will become mapped into the address space of the process in the future.
/// </summary>
Future = LinuxNative.MCL_FUTURE,
/// <summary>
/// Lock pages that are currently mapped into the address space of the process and mark all pages
/// that will become mapped into the address space of the process in the future to be locked
/// when they are faulted in.
/// </summary>
OnFault = LinuxNative.MCL_ONFAULT,
}