public void SignalObject(KSynchronizationObject syncObj) { _system.CriticalSection.Enter(); if (syncObj.IsSignaled()) { LinkedListNode <KThread> node = syncObj.WaitingThreads.First; while (node != null) { KThread thread = node.Value; if ((thread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused) { thread.SignaledObj = syncObj; thread.ObjSyncResult = KernelResult.Success; thread.Reschedule(ThreadSchedState.Running); } node = node.Next; } } _system.CriticalSection.Leave(); }
public static void Wait(KernelContext context, LinkedList <KThread> threadList, object mutex, long timeout) { KThread currentThread = context.Scheduler.GetCurrentThread(); context.CriticalSection.Enter(); Monitor.Exit(mutex); currentThread.Withholder = threadList; currentThread.Reschedule(ThreadSchedState.Paused); currentThread.WithholderNode = threadList.AddLast(currentThread); if (currentThread.ShallBeTerminated || currentThread.SchedFlags == ThreadSchedState.TerminationPending) { threadList.Remove(currentThread.WithholderNode); currentThread.Reschedule(ThreadSchedState.Running); currentThread.Withholder = null; context.CriticalSection.Leave(); } else { if (timeout > 0) { context.TimeManager.ScheduleFutureInvocation(currentThread, timeout); } context.CriticalSection.Leave(); if (timeout > 0) { context.TimeManager.UnscheduleFutureInvocation(currentThread); } } Monitor.Enter(mutex); }
public KernelResult ArbitrateLock(int ownerHandle, ulong mutexAddress, int requesterHandle) { KThread currentThread = KernelStatic.GetCurrentThread(); _context.CriticalSection.Enter(); currentThread.SignaledObj = null; currentThread.ObjSyncResult = KernelResult.Success; KProcess currentProcess = KernelStatic.GetCurrentProcess(); if (!KernelTransfer.UserToKernelInt32(_context, mutexAddress, out int mutexValue)) { _context.CriticalSection.Leave(); return(KernelResult.InvalidMemState); } if (mutexValue != (ownerHandle | HasListenersMask)) { _context.CriticalSection.Leave(); return(0); } KThread mutexOwner = currentProcess.HandleTable.GetObject <KThread>(ownerHandle); if (mutexOwner == null) { _context.CriticalSection.Leave(); return(KernelResult.InvalidHandle); } currentThread.MutexAddress = mutexAddress; currentThread.ThreadHandleForUserMutex = requesterHandle; mutexOwner.AddMutexWaiter(currentThread); currentThread.Reschedule(ThreadSchedState.Paused); _context.CriticalSection.Leave(); _context.CriticalSection.Enter(); if (currentThread.MutexOwner != null) { currentThread.MutexOwner.RemoveMutexWaiter(currentThread); } _context.CriticalSection.Leave(); return(currentThread.ObjSyncResult); }
public static void NotifyAll(KernelContext context, LinkedList <KThread> threadList) { context.CriticalSection.Enter(); LinkedListNode <KThread> node = threadList.First; for (; node != null; node = threadList.First) { KThread thread = node.Value; threadList.Remove(thread.WithholderNode); thread.Withholder = null; thread.Reschedule(ThreadSchedState.Running); } context.CriticalSection.Leave(); }
public KernelResult WaitProcessWideKeyAtomic( ulong mutexAddress, ulong condVarAddress, int threadHandle, long timeout) { _context.CriticalSection.Enter(); KThread currentThread = KernelStatic.GetCurrentThread(); currentThread.SignaledObj = null; currentThread.ObjSyncResult = KernelResult.TimedOut; if (currentThread.ShallBeTerminated || currentThread.SchedFlags == ThreadSchedState.TerminationPending) { _context.CriticalSection.Leave(); return(KernelResult.ThreadTerminating); } (KernelResult result, _) = MutexUnlock(currentThread, mutexAddress); if (result != KernelResult.Success) { _context.CriticalSection.Leave(); return(result); } currentThread.MutexAddress = mutexAddress; currentThread.ThreadHandleForUserMutex = threadHandle; currentThread.CondVarAddress = condVarAddress; _condVarThreads.Add(currentThread); if (timeout != 0) { currentThread.Reschedule(ThreadSchedState.Paused); if (timeout > 0) { _context.TimeManager.ScheduleFutureInvocation(currentThread, timeout); } } _context.CriticalSection.Leave(); if (timeout > 0) { _context.TimeManager.UnscheduleFutureInvocation(currentThread); } _context.CriticalSection.Enter(); if (currentThread.MutexOwner != null) { currentThread.MutexOwner.RemoveMutexWaiter(currentThread); } _condVarThreads.Remove(currentThread); _context.CriticalSection.Leave(); return(currentThread.ObjSyncResult); }
public KernelResult WaitFor(KSynchronizationObject[] syncObjs, long timeout, out int handleIndex) { handleIndex = 0; KernelResult result = KernelResult.TimedOut; _system.CriticalSection.Enter(); //Check if objects are already signaled before waiting. for (int index = 0; index < syncObjs.Length; index++) { if (!syncObjs[index].IsSignaled()) { continue; } handleIndex = index; _system.CriticalSection.Leave(); return(0); } if (timeout == 0) { _system.CriticalSection.Leave(); return(result); } KThread currentThread = _system.Scheduler.GetCurrentThread(); if (currentThread.ShallBeTerminated || currentThread.SchedFlags == ThreadSchedState.TerminationPending) { result = KernelResult.ThreadTerminating; } else if (currentThread.SyncCancelled) { currentThread.SyncCancelled = false; result = KernelResult.Cancelled; } else { LinkedListNode <KThread>[] syncNodes = new LinkedListNode <KThread> [syncObjs.Length]; for (int index = 0; index < syncObjs.Length; index++) { syncNodes[index] = syncObjs[index].AddWaitingThread(currentThread); } currentThread.WaitingSync = true; currentThread.SignaledObj = null; currentThread.ObjSyncResult = result; currentThread.Reschedule(ThreadSchedState.Paused); if (timeout > 0) { _system.TimeManager.ScheduleFutureInvocation(currentThread, timeout); } _system.CriticalSection.Leave(); currentThread.WaitingSync = false; if (timeout > 0) { _system.TimeManager.UnscheduleFutureInvocation(currentThread); } _system.CriticalSection.Enter(); result = currentThread.ObjSyncResult; handleIndex = -1; for (int index = 0; index < syncObjs.Length; index++) { syncObjs[index].RemoveWaitingThread(syncNodes[index]); if (syncObjs[index] == currentThread.SignaledObj) { handleIndex = index; } } } _system.CriticalSection.Leave(); return(result); }
public KernelResult WaitForAddressIfLessThan( ulong address, int value, bool shouldDecrement, long timeout) { KThread currentThread = _system.Scheduler.GetCurrentThread(); _system.CriticalSection.Enter(); if (currentThread.ShallBeTerminated || currentThread.SchedFlags == ThreadSchedState.TerminationPending) { _system.CriticalSection.Leave(); return(KernelResult.ThreadTerminating); } currentThread.SignaledObj = null; currentThread.ObjSyncResult = KernelResult.TimedOut; KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); if (!KernelTransfer.UserToKernelInt32(_system, address, out int currentValue)) { _system.CriticalSection.Leave(); return(KernelResult.InvalidMemState); } if (shouldDecrement) { currentValue = currentProcess.CpuMemory.AtomicDecrementInt32((long)address) + 1; } if (currentValue < value) { if (timeout == 0) { _system.CriticalSection.Leave(); return(KernelResult.TimedOut); } currentThread.MutexAddress = address; currentThread.WaitingInArbitration = true; InsertSortedByPriority(ArbiterThreads, currentThread); currentThread.Reschedule(ThreadSchedState.Paused); if (timeout > 0) { _system.TimeManager.ScheduleFutureInvocation(currentThread, timeout); } _system.CriticalSection.Leave(); if (timeout > 0) { _system.TimeManager.UnscheduleFutureInvocation(currentThread); } _system.CriticalSection.Enter(); if (currentThread.WaitingInArbitration) { ArbiterThreads.Remove(currentThread); currentThread.WaitingInArbitration = false; } _system.CriticalSection.Leave(); return((KernelResult)currentThread.ObjSyncResult); } _system.CriticalSection.Leave(); return(KernelResult.InvalidState); }