示例#1
0
        public virtual int sceKernelCreateLwMutex(TPointer workAreaAddr, string name, int attr, int count, TPointer option)
        {
            SceKernelLwMutexInfo info = new SceKernelLwMutexInfo(workAreaAddr, name, count, attr);

            lwMutexMap[info.uid] = info;

            // Return 0 in case of no error, do not return the UID of the created mutex
            return(0);
        }
示例#2
0
        private bool removeWaitingThread(SceKernelThreadInfo thread)
        {
            SceKernelLwMutexInfo info = lwMutexMap[thread.wait.LwMutex_id];

            if (info == null)
            {
                return(false);
            }

            info.threadWaitingList.removeWaitingThread(thread);

            return(true);
        }
示例#3
0
        public virtual int sceKernelReferLwMutexStatusByID(int uid, TPointer addr)
        {
            SceKernelLwMutexInfo info = lwMutexMap[uid];

            if (info == null)
            {
                Console.WriteLine("sceKernelReferLwMutexStatus unknown UID " + uid.ToString("x"));
                return(ERROR_KERNEL_LWMUTEX_NOT_FOUND);
            }

            info.write(addr);

            return(0);
        }
示例#4
0
        public virtual int sceKernelDeleteLwMutex(TPointer workAreaAddr)
        {
            int uid = workAreaAddr.getValue32();

            SceKernelLwMutexInfo info = lwMutexMap.Remove(uid);

            if (info == null)
            {
                Console.WriteLine("sceKernelDeleteLwMutex unknown UID " + uid.ToString("x"));
                return(ERROR_KERNEL_LWMUTEX_NOT_FOUND);
            }

            workAreaAddr.setValue32(0);             // Clear uid.
            onLwMutexDeleted(uid);

            return(0);
        }
示例#5
0
        public virtual int sceKernelUnlockLwMutex(TPointer workAreaAddr, int count)
        {
            int uid = workAreaAddr.getValue32();
            SceKernelLwMutexInfo info = lwMutexMap[uid];

            if (info == null)
            {
                if (uid == 0)
                {
                    // Avoid spamming messages for uid==0
                    //if (log.DebugEnabled)
                    {
                        Console.WriteLine(string.Format("sceKernelUnlockLwMutex unknown uid=0x{0:X}", uid));
                    }
                }
                else
                {
                    Console.WriteLine(string.Format("sceKernelUnlockLwMutex unknown uid=0x{0:X}", uid));
                }
                return(ERROR_KERNEL_LWMUTEX_NOT_FOUND);
            }
            if (info.lockedCount == 0)
            {
                Console.WriteLine("sceKernelUnlockLwMutex not locked");
                return(ERROR_KERNEL_LWMUTEX_UNLOCKED);
            }
            if (info.lockedCount < 0)
            {
                Console.WriteLine("sceKernelUnlockLwMutex underflow");
                return(ERROR_KERNEL_LWMUTEX_UNLOCK_UNDERFLOW);
            }

            info.lockedCount -= count;
            if (info.lockedCount == 0)
            {
                info.threadid = -1;
                onLwMutexModified(info);
            }

            return(0);
        }
示例#6
0
            public virtual bool continueWaitState(SceKernelThreadInfo thread, ThreadWaitInfo wait)
            {
                // Check if the thread has to continue its wait state or if the lwmutex
                // has been unlocked during the callback execution.
                SceKernelLwMutexInfo info = outerInstance.lwMutexMap[wait.LwMutex_id];

                if (info == null)
                {
                    thread.cpuContext._v0 = ERROR_KERNEL_LWMUTEX_NOT_FOUND;
                    return(false);
                }

                // Check the lwmutex.
                if (outerInstance.tryLockLwMutex(info, wait.LwMutex_count, thread))
                {
                    info.threadWaitingList.removeWaitingThread(thread);
                    thread.cpuContext._v0 = 0;
                    return(false);
                }

                return(true);
            }
示例#7
0
 private bool tryLockLwMutex(SceKernelLwMutexInfo info, int count, SceKernelThreadInfo thread)
 {
     if (info.lockedCount == 0)
     {
         // If the lwmutex is not locked, allow this thread to lock it.
         info.threadid     = thread.uid;
         info.lockedCount += count;
         return(true);
     }
     else if (info.threadid == thread.uid)
     {
         // If the lwmutex is already locked, but it's trying to be locked by the same thread
         // that acquired it initially, check if recursive locking is allowed.
         // If not, return an error.
         if (((info.attr & PSP_LWMUTEX_ATTR_ALLOW_RECURSIVE) == PSP_LWMUTEX_ATTR_ALLOW_RECURSIVE))
         {
             info.lockedCount += count;
             return(true);
         }
     }
     return(false);
 }
示例#8
0
        private void onLwMutexModified(SceKernelLwMutexInfo info)
        {
            ThreadManForUser threadMan  = Modules.ThreadManForUserModule;
            bool             reschedule = false;

            SceKernelThreadInfo checkedThread = null;

            while (true)
            {
                SceKernelThreadInfo thread = info.threadWaitingList.getNextWaitingThread(checkedThread);
                if (thread == null)
                {
                    break;
                }
                if (tryLockLwMutex(info, thread.wait.LwMutex_count, thread))
                {
                    //if (log.DebugEnabled)
                    {
                        Console.WriteLine(string.Format("onLwMutexModified waking thread {0}", thread));
                    }
                    // New thread is taking control of LwMutex.
                    info.threadid = thread.uid;
                    info.threadWaitingList.removeWaitingThread(thread);
                    thread.cpuContext._v0 = 0;
                    threadMan.hleChangeThreadState(thread, PSP_THREAD_READY);
                    reschedule = true;
                }
                else
                {
                    checkedThread = thread;
                }
            }

            // Reschedule only if threads waked up.
            if (reschedule)
            {
                Modules.ThreadManForUserModule.hleRescheduleCurrentThread();
            }
        }
示例#9
0
        private int hleKernelLockLwMutex(int uid, int count, TPointer32 timeoutAddr, bool wait, bool doCallbacks)
        {
            SceKernelLwMutexInfo info = lwMutexMap[uid];

            if (info == null)
            {
                if (uid == 0)
                {
                    // Avoid spamming messages for uid==0
                    //if (log.DebugEnabled)
                    {
//JAVA TO C# CONVERTER TODO TASK: The following line has a Java format specifier which cannot be directly translated to .NET:
//ORIGINAL LINE: Console.WriteLine(String.format("hleKernelLockLwMutex uid=%d, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b -  - unknown UID", uid, count, timeoutAddr, wait, doCallbacks));
                        Console.WriteLine(string.Format("hleKernelLockLwMutex uid=%d, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b -  - unknown UID", uid, count, timeoutAddr, wait, doCallbacks));
                    }
                }
                else
                {
//JAVA TO C# CONVERTER TODO TASK: The following line has a Java format specifier which cannot be directly translated to .NET:
//ORIGINAL LINE: Console.WriteLine(String.format("hleKernelLockLwMutex uid=%d, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b -  - unknown UID", uid, count, timeoutAddr, wait, doCallbacks));
                    Console.WriteLine(string.Format("hleKernelLockLwMutex uid=%d, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b -  - unknown UID", uid, count, timeoutAddr, wait, doCallbacks));
                }
                return(ERROR_KERNEL_LWMUTEX_NOT_FOUND);
            }

            ThreadManForUser    threadMan     = Modules.ThreadManForUserModule;
            SceKernelThreadInfo currentThread = threadMan.CurrentThread;

            if (!tryLockLwMutex(info, count, currentThread))
            {
                //if (log.DebugEnabled)
                {
//JAVA TO C# CONVERTER TODO TASK: The following line has a Java format specifier which cannot be directly translated to .NET:
//ORIGINAL LINE: Console.WriteLine(String.format("hleKernelLockLwMutex %s, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b - fast check failed", info.toString(), count, timeoutAddr, wait, doCallbacks));
                    Console.WriteLine(string.Format("hleKernelLockLwMutex %s, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b - fast check failed", info.ToString(), count, timeoutAddr, wait, doCallbacks));
                }
                if (wait && info.threadid != currentThread.uid)
                {
                    // Failed, but it's ok, just wait a little
                    info.threadWaitingList.addWaitingThread(currentThread);
                    // Wait on a specific lwmutex
                    currentThread.wait.LwMutex_id    = uid;
                    currentThread.wait.LwMutex_count = count;
                    threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_LWMUTEX, uid, lwMutexWaitStateChecker, timeoutAddr.Address, doCallbacks);
                }
                else
                {
                    if ((info.attr & PSP_LWMUTEX_ATTR_ALLOW_RECURSIVE) != PSP_LWMUTEX_ATTR_ALLOW_RECURSIVE)
                    {
                        return(ERROR_KERNEL_LWMUTEX_RECURSIVE_NOT_ALLOWED);
                    }
                    return(ERROR_KERNEL_LWMUTEX_LOCKED);
                }
            }
            else
            {
                // Success, do not reschedule the current thread.
                //if (log.DebugEnabled)
                {
//JAVA TO C# CONVERTER TODO TASK: The following line has a Java format specifier which cannot be directly translated to .NET:
//ORIGINAL LINE: Console.WriteLine(String.format("hleKernelLockLwMutex %s, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b - fast check succeeded", info.toString(), count, timeoutAddr, wait, doCallbacks));
                    Console.WriteLine(string.Format("hleKernelLockLwMutex %s, count=%d, timeout_addr=%s, wait=%b, doCallbacks=%b - fast check succeeded", info.ToString(), count, timeoutAddr, wait, doCallbacks));
                }
            }

            return(0);
        }