unknownbrackets / ps2autotests

A set of test programs run on a PS2, with accompanying results.
ISC License
25 stars 7 forks source link

Added EE SuspendThread and ResumeThread tests. #19

Closed jpd002 closed 8 years ago

jpd002 commented 8 years ago

These test SuspendThread and ResumeThread.

There's one odd thing about SuspendThread, which is the possibility to suspend the current thread. The thread continues its execution even through it's in SUSPEND state and is put back into RUN when a reschedule occurs. I think it would be hard to isolate that behavior which is why I didn't go any further in that direction except to show that it goes back to RUN after reschedule.

unknownbrackets commented 8 years ago

Hmm, the only thing I wonder about that situation is how rescheduling works.

For example, on the PSP, these things get handled in a very specific way that some games depend on. As an example, consider two threads A and B with the same priority, 0x20.

While A is running, if it starts a better-priority thread (e.g. 0x10) C, execution would be moved to C. When it's complete, iirc, A would continue running. B would never have gotten a chance.

However, A can also call a function to "rotate" the threadqueue, which would cause B to be scheduled.

Suspending the current thread might be a trick that allows you to drop it to the end of that priority's threadqueue. But I'm not sure how threading works exactly on the PS2.

-[Unknown]

jpd002 commented 8 years ago

Yeah, it works the same on the PS2. In theory, once a thread is put in wait or suspend state, it's removed from the priority's queue and it's put back at the end of that queue once it's back in ready state.

There's a RotateThreadReadyQueue system call too on the PS2, so I don't think people would have used that specific quirk in SuspendThread to achieve that. But it might be interesting to test whether or not ResumeThread causes the thread to be put at the end of the priority queue. I don't really know how I would test that though. I guess I could take a look at pspautotests for an example.

unknownbrackets commented 8 years ago

Well, I'll merge this for now, can always modify it more later.

What I've done in the past is had thread B essentially do this:

static bool thread_b_scheduled = false;

static int thread_func_b(void *argp) {
    while (true) {
        thread_b_scheduled = true;
        RotateThreadReadyQueue();
    }
    return 0;
}

/// ...
thread_b_scheduled = false;
// Do stuff.
printf("B: %d", thread_b_scheduled);

-[Unknown]

jpd002 commented 8 years ago

Oh, that's pretty clever. I might give this a try.

Thanks!