unknownbrackets / ps2autotests

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

Added thread_stat test #5

Closed jpd002 closed 9 years ago

jpd002 commented 9 years ago

I've been toying around with EE kernel tests and here's the first one I've done that I'm happy with.

I've looked at how pspautotests were doing their threading tests and saw they were using a "schedf" function which seemed to solve an unwanted rescheduling problem I had while conducting my own tests. They also have "checkpoint" and "checkpointNext" functions which I haven't studied yet which might be useful on the PS2 too.

The EE kernel performs very little validation, so it will accept almost any garbage we will throw at it. For example, calling ReferThreadStatus on a deleted thread doesn't return an error, so, that's why I didn't include that test here. Hard to say if it's undefined behavior or not and if it's really worth testing.

unknownbrackets commented 9 years ago

Right, good ol' schedf. The issue was that IO (such as printf()) blocks the calling thread. This will probably be an issue in any thread implementation.

The checkpoint function is a useful thing in testing thread scheduling in general. Basically, it does the following:

  1. On init, it starts a thread with slightly worse priority than (or was it the same as?) the current thread.
  2. You run your code (e.g. the func that you'll log the return value of.)
  3. You call checkpoint() with the return value.
  4. It determines if that thread ran. If it did, this means the code (item 2) blocked or rescheduled in some way.
  5. In the results, it writes out an indicator of whether a reschedule happened or not ([r] or [x].)
  6. Automatically flushes the schedf buffer (maybe it does this only at checkpointNext.)

This helps in noticing that certain functions block in interesting or important ways. It also has some options to enable logging of timestamps (e.g. to see the amount of time / cycles a function took.)

Anyway - as to this pull, seems okay.

Should we put the thread funcs under tests/kernel/ee/thread/ or something? Depends on how many there are. If we might have 4-5 test files I think it'd be better.

IMHO, if the kernel allows referring a thread that was deleted, that sounds like behavior some game might depend on (even if by accident.) I think anything is fair game that a game could reasonably cause to happen.

If the results aren't deterministic it gets tricky, though...

As an example, the pspautotests for lwmutexes test some "impossible" cases with a corrupt lwmutex struct, iirc. We've rarely had issues with the lwmutex implementation because of these thorough tests.

-[Unknown]

unknownbrackets commented 9 years ago

By the way, I merged this because I think it can possibly be improved but no matter what, it's a useful test.

-[Unknown]

jpd002 commented 9 years ago

Thanks for the merge. Yes, it can definitively be improved.

I was thinking of creating a test for every thread function (ie.: create, delete, terminate, start, sleep/wakeup, rotatereadyqueue, referstat etc.) testing all their parameters and possible edge cases. So, yeah, I agree that it would be better to put them in a separate directory. I will do that once I get the next test ready.

As for referring to a deleted thread's status, I guess we could test that too, but I wouldn't really know where to draw the line for testing undocumented/undefined stuff. I think it could get very tricky to test everything (CreateThread comes to mind, nothing inside the create struct is validated), but I agree that it'll be necessary if we want an accurate emulator.

Thanks for the info regarding schedf and checkpoint. I'll take a closer look at checkpoint and see how it's used in pspautotests.