Exemplo n.º 1
0
        public long ArbitrateLock(
            Process Process,
            AMemory Memory,
            int OwnerHandle,
            long MutexAddress,
            int RequesterHandle)
        {
            System.CriticalSectionLock.Lock();

            KThread CurrentThread = System.Scheduler.GetCurrentThread();

            CurrentThread.SignaledObj   = null;
            CurrentThread.ObjSyncResult = 0;

            if (!UserToKernelInt32(Memory, MutexAddress, out int MutexValue))
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));;
            }

            if (MutexValue != (OwnerHandle | HasListenersMask))
            {
                System.CriticalSectionLock.Unlock();

                return(0);
            }

            KThread MutexOwner = Process.HandleTable.GetObject <KThread>(OwnerHandle);

            if (MutexOwner == null)
            {
                System.CriticalSectionLock.Unlock();

                return(MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle));
            }

            CurrentThread.MutexAddress             = MutexAddress;
            CurrentThread.ThreadHandleForUserMutex = RequesterHandle;

            MutexOwner.AddMutexWaiter(CurrentThread);

            CurrentThread.Reschedule(ThreadSchedState.Paused);

            System.CriticalSectionLock.Unlock();
            System.CriticalSectionLock.Lock();

            if (CurrentThread.MutexOwner != null)
            {
                CurrentThread.MutexOwner.RemoveMutexWaiter(CurrentThread);
            }

            System.CriticalSectionLock.Unlock();

            return((uint)CurrentThread.ObjSyncResult);
        }
Exemplo n.º 2
0
        public long ArbitrateLock(int ownerHandle, long mutexAddress, int requesterHandle)
        {
            KThread currentThread = _system.Scheduler.GetCurrentThread();

            _system.CriticalSection.Enter();

            currentThread.SignaledObj   = null;
            currentThread.ObjSyncResult = 0;

            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

            if (!KernelTransfer.UserToKernelInt32(_system, mutexAddress, out int mutexValue))
            {
                _system.CriticalSection.Leave();

                return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));
            }

            if (mutexValue != (ownerHandle | HasListenersMask))
            {
                _system.CriticalSection.Leave();

                return(0);
            }

            KThread mutexOwner = currentProcess.HandleTable.GetObject <KThread>(ownerHandle);

            if (mutexOwner == null)
            {
                _system.CriticalSection.Leave();

                return(MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle));
            }

            currentThread.MutexAddress             = mutexAddress;
            currentThread.ThreadHandleForUserMutex = requesterHandle;

            mutexOwner.AddMutexWaiter(currentThread);

            currentThread.Reschedule(ThreadSchedState.Paused);

            _system.CriticalSection.Leave();
            _system.CriticalSection.Enter();

            if (currentThread.MutexOwner != null)
            {
                currentThread.MutexOwner.RemoveMutexWaiter(currentThread);
            }

            _system.CriticalSection.Leave();

            return((uint)currentThread.ObjSyncResult);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }