Post Reply 
 
Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Darkstalkers Chronicle: The Chaos Tower
01-07-2014, 02:11 AM
Post: #17
RE: Darkstalkers Chronicle The Chaos Tower
So suddenly it's at 50? Hmm. Oh wait.

326=sceKernelCreateThread(name=Task Level0, entry=0885575c, prio=32, stacksize=12288)
sceKernelStartThread(thread=326, argSize=0, argPtr=00000000)
Unable to remove thread 326 from queue 50 - was not there <-- I thought this was wrong but it isn't, 0x32 = 50.

...

sceKernelChangeThreadPriority(326, 63) <-- at this point it should be 63 no matter what.
Unable to remove thread 326 from queue 63 - was not there <-- okay, good

...

Unable to remove thread 326 from queue 63 - was not there <-- okay, still fine
sceKernelTerminateThread(326)
Unable to remove thread 326 from queue 50 - was not there <-- what this means is that initPriority was 50
Kernel: Bad object handle 326 (00000146)
ACK ACK ACK ACK Invalid thread id 326 on thread queue <-- so then, where is it on the queue?

I'm guessing it must somehow have managed to get back onto the queue somewhere, but not sure how?

This calls for more drastic changes. Change __KernelNextThread() to:

Code:
Thread *__KernelNextThread() {
    SceUID bestThread;
    u32 popped_prio;

    // If the current thread is running, it's a valid candidate.
    Thread *cur = __GetCurrentThread();
    if (cur && cur->isRunning())
    {
        bestThread = threadReadyQueue.pop_first_better(cur->nt.currentPriority, popped_prio);
        if (bestThread != 0)
            __KernelChangeReadyState(cur, currentThread, true);
    }
    else
        bestThread = threadReadyQueue.pop_first(popped_prio);

    // Assume threadReadyQueue has not become corrupt.
    if (bestThread != 0) {
        u32 errorIgnored;
        Thread *t = kernelObjects.Get<Thread>(bestThread, errorIgnored);
        if (t == NULL && bestThread != 0) {
            NOTICE_LOG(HLE, "ACK ACK ACK ACK Invalid thread id %d on thread queue at %d", bestThread, popped_prio);
            // popped_prio is the interesting thing here.
            DebugBreak();
            // Try, try again?
            t = __KernelNextThread();
        }
        if (t == NULL) {
            NOTICE_LOG(HLE, "ACK ACK ACK ACK Thread queue empty");
            DebugBreak();
            // Just brute force it, hopefully...
            return kernelObjects.Get<Thread>(threadIdleID[0], errorIgnored);
        }
        return t;
    } else {
        return 0;
    }
}

And then, change these:

Code:
inline SceUID pop_first()
        {
                Queue *cur = first;
                while (cur != invalid())
                {
                        if (cur->end - cur->first > 0)
                                return cur->data[cur->first++];
                        cur = cur->next;
                }

                _dbg_assert_msg_(SCEKERNEL, false, "ThreadQueueList should not be empty.");
                return 0;
        }

        inline SceUID pop_first_better(u32 priority)
        {
                Queue *cur = first;
                Queue *stop = &queues[priority];
                while (cur < stop)
                {
                        if (cur->end - cur->first > 0)
                                return cur->data[cur->first++];
                        cur = cur->next;
                }

                return 0;
        }

To:

Code:
inline SceUID pop_first(u32 &popped_priority)
        {
                for (int i = 0; i < NUM_QUEUES; ++i)
                {
                        if (queues[i].data == NULL)
                                continue;

                        Queue *cur = &queues[i];
                        popped_priority = i;
                        if (cur->end - cur->first > 0)
                                return cur->data[cur->first++];
                }

                _dbg_assert_msg_(SCEKERNEL, false, "ThreadQueueList should not be empty.");
                return 0;
        }

        inline SceUID pop_first_better(u32 priority, u32 &popped_priority)
        {
                return pop_first(popped_priority);
        }

This should identify which queue priority level the thread id came from (it'll be slower but won't matter much on desktop.)

If it's 50 or 63, then I guess somehow it's being added back to the queue somewhere after being terminated? If it's something else... then gotta figure out when it's added to that level.

-[Unknown]
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: Darkstalkers Chronicle The Chaos Tower - [Unknown] - 01-07-2014 02:11 AM

Forum Jump: