private (long, KThread) MutexUnlock(KThread CurrentThread, long MutexAddress) { KThread NewOwnerThread = CurrentThread.RelinquishMutex(MutexAddress, out int Count); int MutexValue = 0; if (NewOwnerThread != null) { MutexValue = NewOwnerThread.ThreadHandleForUserMutex; if (Count >= 2) { MutexValue |= HasListenersMask; } NewOwnerThread.SignaledObj = null; NewOwnerThread.ObjSyncResult = 0; NewOwnerThread.ReleaseAndResume(); } long Result = 0; if (!KernelTransfer.KernelToUserInt32(System, MutexAddress, MutexValue)) { Result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); } return(Result, NewOwnerThread); }
private (long, KThread) MutexUnlock(KThread currentThread, long mutexAddress) { KThread newOwnerThread = currentThread.RelinquishMutex(mutexAddress, out int count); int mutexValue = 0; if (newOwnerThread != null) { mutexValue = newOwnerThread.ThreadHandleForUserMutex; if (count >= 2) { mutexValue |= HasListenersMask; } newOwnerThread.SignaledObj = null; newOwnerThread.ObjSyncResult = 0; newOwnerThread.ReleaseAndResume(); } long result = 0; if (!KernelTransfer.KernelToUserInt32(_system, mutexAddress, mutexValue)) { result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); } return(result, newOwnerThread); }
private void MutexUnlock(AMemory Memory, KThread CurrentThread, long MutexAddress) { KThread NewOwnerThread = CurrentThread.RelinquishMutex(MutexAddress, out int Count); int MutexValue = 0; if (NewOwnerThread != null) { MutexValue = NewOwnerThread.ThreadHandleForUserMutex; if (Count >= 2) { MutexValue |= HasListenersMask; } NewOwnerThread.SignaledObj = null; NewOwnerThread.ObjSyncResult = 0; NewOwnerThread.ReleaseAndResume(); } Memory.WriteInt32ToSharedAddr(MutexAddress, MutexValue); }
private KThread TryAcquireMutex(KThread Requester) { long Address = Requester.MutexAddress; KProcess CurrentProcess = System.Scheduler.GetCurrentProcess(); CurrentProcess.CpuMemory.SetExclusive(0, Address); if (!KernelTransfer.UserToKernelInt32(System, Address, out int MutexValue)) { //Invalid address. CurrentProcess.CpuMemory.ClearExclusive(0); Requester.SignaledObj = null; Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return(null); } while (true) { if (CurrentProcess.CpuMemory.TestExclusive(0, Address)) { if (MutexValue != 0) { //Update value to indicate there is a mutex waiter now. CurrentProcess.CpuMemory.WriteInt32(Address, MutexValue | HasListenersMask); } else { //No thread owning the mutex, assign to requesting thread. CurrentProcess.CpuMemory.WriteInt32(Address, Requester.ThreadHandleForUserMutex); } CurrentProcess.CpuMemory.ClearExclusiveForStore(0); break; } CurrentProcess.CpuMemory.SetExclusive(0, Address); MutexValue = CurrentProcess.CpuMemory.ReadInt32(Address); } if (MutexValue == 0) { //We now own the mutex. Requester.SignaledObj = null; Requester.ObjSyncResult = 0; Requester.ReleaseAndResume(); return(null); } MutexValue &= ~HasListenersMask; KThread MutexOwner = CurrentProcess.HandleTable.GetObject <KThread>(MutexValue); if (MutexOwner != null) { //Mutex already belongs to another thread, wait for it. MutexOwner.AddMutexWaiter(Requester); } else { //Invalid mutex owner. Requester.SignaledObj = null; Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); Requester.ReleaseAndResume(); } return(MutexOwner); }
private KThread TryAcquireMutex(Process Process, AMemory Memory, KThread Requester) { int Core = Requester.CurrentCore; long Address = Requester.MutexAddress; Memory.SetExclusive(Core, Address); int MutexValue = Memory.ReadInt32(Address); while (MutexValue != 0) { if (Memory.TestExclusive(Core, Address)) { if (MutexValue != 0) { //Update value to indicate there is a mutex waiter now. Memory.WriteInt32(Address, MutexValue | HasListenersMask); } else { //No thread owning the mutex, assign to requesting thread. Memory.WriteInt32(Address, Requester.ThreadHandleForUserMutex); } Memory.ClearExclusiveForStore(Core); break; } Memory.SetExclusive(Core, Address); MutexValue = Memory.ReadInt32(Address); } if (MutexValue == 0) { //We now own the mutex. Requester.SignaledObj = null; Requester.ObjSyncResult = 0; Requester.ReleaseAndResume(); return(null); } MutexValue &= ~HasListenersMask; KThread MutexOwner = Process.HandleTable.GetData <KThread>(MutexValue); if (MutexOwner != null) { //Mutex already belongs to another thread, wait for it. MutexOwner.AddMutexWaiter(Requester); } else { //Invalid mutex owner. Requester.SignaledObj = null; Requester.ObjSyncResult = (int)MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); Requester.ReleaseAndResume(); } return(MutexOwner); }