XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
namespace XFESystem.NativeKernel;

// Generation-tagged handles prevent a closed handle from targeting a reused slot.
// Waiters are real parked kernel threads; manual and auto reset have separate state.
public static unsafe class KernelEvents
{
    const uint Capacity = 128;
    public const uint Timeout = 258, Failure = 0xffffffff;
    static ulong* _events;
    static ulong _generation;
    public static bool Initialize() { _events = (ulong*)Native.Storage(9); return _events != null; }
    static int Slot(ulong handle)
    {
        uint number = (uint)(handle & 255);
        if (_events == null || number == 0 || number > Capacity) return -1;
        uint slot = number - 1;
        return _events[slot * 4] == handle ? (int)slot : -1;
    }
    public static ulong Create(bool manual, bool initial)
    {
        ulong flags = Native.IrqSave(), result = 0;
        if (_events != null)
            for (uint i = 0; i < Capacity; i++) if (_events[i * 4] == 0)
            {
                result = (++_generation << 8) | (i + 1);
                _events[i * 4] = result; _events[i * 4 + 1] = manual ? 1UL : 0UL;
                _events[i * 4 + 2] = initial ? 1UL : 0UL; break;
            }
        Native.IrqRestore(flags); return result;
    }
    public static bool Close(ulong handle)
    {
        ulong flags = Native.IrqSave(); int slot = Slot(handle);
        if (slot >= 0) { _events[slot * 4] = 0; Threads.WakeEvent(handle); }
        Native.IrqRestore(flags); return slot >= 0;
    }
    public static bool Set(ulong handle)
    {
        ulong flags = Native.IrqSave(); int slot = Slot(handle);
        if (slot >= 0) { _events[slot * 4 + 2] = 1; Threads.WakeEvent(handle); }
        Native.IrqRestore(flags); return slot >= 0;
    }
    public static bool Reset(ulong handle)
    {
        ulong flags = Native.IrqSave(); int slot = Slot(handle);
        if (slot >= 0) _events[slot * 4 + 2] = 0;
        Native.IrqRestore(flags); return slot >= 0;
    }
    public static uint Wait(ulong* handles, uint count, uint milliseconds)
    {
        if (handles == null || count == 0 || count > 64 || !Threads.Ready) return Failure;
        ulong deadline = milliseconds == 0xffffffff ? ~0UL : MonotonicClock.Nanoseconds() + (ulong)milliseconds * 1000000;
        for (;;)
        {
            ulong flags = Native.IrqSave();
            for (uint i = 0; i < count; i++)
            {
                int slot = Slot(handles[i]);
                if (slot < 0) { Native.IrqRestore(flags); return Failure; }
                if (_events[slot * 4 + 2] != 0)
                {
                    if (_events[slot * 4 + 1] == 0) _events[slot * 4 + 2] = 0;
                    Native.IrqRestore(flags); return i;
                }
            }
            if (MonotonicClock.Nanoseconds() >= deadline) { Native.IrqRestore(flags); return Timeout; }
            Threads.ParkEvent(count == 1 ? handles[0] : ~0UL, deadline);
            Native.IrqRestore(flags);
        }
    }
}