Example #1
0
        private void SvcArbitrateLock(AThreadState ThreadState)
        {
            int  OwnerThreadHandle      = (int)ThreadState.X0;
            long MutexAddress           = (long)ThreadState.X1;
            int  RequestingThreadHandle = (int)ThreadState.X2;

            KThread OwnerThread = Process.HandleTable.GetData <KThread>(OwnerThreadHandle);

            if (OwnerThread == null)
            {
                Logging.Warn(LogClass.KernelSvc, $"Invalid owner thread handle 0x{OwnerThreadHandle:x8}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);

                return;
            }

            KThread RequestingThread = Process.HandleTable.GetData <KThread>(RequestingThreadHandle);

            if (RequestingThread == null)
            {
                Logging.Warn(LogClass.KernelSvc, $"Invalid requesting thread handle 0x{RequestingThreadHandle:x8}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);

                return;
            }

            MutualExclusion Mutex = GetMutex(MutexAddress);

            Mutex.WaitForLock(RequestingThread, OwnerThreadHandle);

            ThreadState.X0 = 0;
        }
Example #2
0
        private void SvcWaitProcessWideKeyAtomic(AThreadState ThreadState)
        {
            long  MutexAddress   = (long)ThreadState.X0;
            long  CondVarAddress = (long)ThreadState.X1;
            int   ThreadHandle   = (int)ThreadState.X2;
            ulong Timeout        = ThreadState.X3;

            KThread Thread = Process.HandleTable.GetData <KThread>(ThreadHandle);

            if (Thread == null)
            {
                Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{ThreadHandle:x8}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
            }

            Process.Scheduler.Suspend(Thread.ProcessorId);

            MutualExclusion Mutex = GetMutex(MutexAddress);

            Mutex.Unlock();

            if (!GetCondVar(CondVarAddress).WaitForSignal(Thread, Timeout))
            {
                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.Timeout);

                return;
            }

            Mutex.WaitForLock(Thread);

            Process.Scheduler.Resume(Thread);

            ThreadState.X0 = 0;
        }