Delegate functions in PSPSDK (for cross-thread operations)
Delegate functions in PSPSDK (for cross-thread operations)
How do I call a 'delegate' function in the PSPSDK?
Basically I am using a class in my main thread, and I launch one of its functions as a new thread. Now from the new thread how do I call a member function but have it run in the context of the main-thread.
Right now I'm using a crude method of setting up some global variables, and continuously checking the variables from the main thread, if a variable is set (by the new thread) the corresponding function is called in the main thread.
Basically I am using a class in my main thread, and I launch one of its functions as a new thread. Now from the new thread how do I call a member function but have it run in the context of the main-thread.
Right now I'm using a crude method of setting up some global variables, and continuously checking the variables from the main thread, if a variable is set (by the new thread) the corresponding function is called in the main thread.
The word delegate has been introduced by microsoft with their C# to mean a function pointer in a managed environment. If i understand, what you are basically asking is how to replicate the obj.Invoke(fnDelegate); to make a thread call a function in its context from another thread. This is not very simple and definitely not straightforward - if there's not a dedcated function that i don't know. A possible way is to pass the function pointer writing in a shared memory location and then unlock a semaphore. At least that's the way used in other c/c++ cross-platform projects.
The semaphore method is basically the same as my global variable stuff. I don't need to go as far as a function pointer because I only need 2 or 3 specific functions which the main thread can decide depending on the value of the variable. However this will cause a delay depending on how often the main thread loops and checks the semaphore (if its a blocking wait then its more or less instant) but I want my main thread to do other processing as well instead of just blocking until the semaphore is unlocked. Since my main thread has a delay of 100000 it will take a short while before the function call occurs.
My specific problem is that I need to call some ordinary sce* functions from inside a syscon_debug_handler. However this is obviously not to be done as it blocks all syscon packets till the function returns and will cause very strange side effects, including hardware malfunction. Hence I'm setting a global from inside the syscon handler and that is being checked by the main thread whether to execute a function. The only problem here is the slight delay caused by the main loop's delaythread function as I don't want it hogging CPU.
My specific problem is that I need to call some ordinary sce* functions from inside a syscon_debug_handler. However this is obviously not to be done as it blocks all syscon packets till the function returns and will cause very strange side effects, including hardware malfunction. Hence I'm setting a global from inside the syscon handler and that is being checked by the main thread whether to execute a function. The only problem here is the slight delay caused by the main loop's delaythread function as I don't want it hogging CPU.
Not totally sure, but maybe threadman callbacks can resolve your problem.
You create the callback in a thread A, and then it can be notified from other thread B with sceKernelNotifyCallback, the function will be executed on context of thread A. However, thread A should be checking for callbacks using sceKernelCheckCallback or having entered in a a sleep/delay/wait state with one of the CB versions of those wait functions.
You create the callback in a thread A, and then it can be notified from other thread B with sceKernelNotifyCallback, the function will be executed on context of thread A. However, thread A should be checking for callbacks using sceKernelCheckCallback or having entered in a a sleep/delay/wait state with one of the CB versions of those wait functions.
Just tried it. In the main thread I used sceKernelDelayThreadCB for delaying.
The function is executing instantly (because the main thread is in DelayCB for most of the time anyway, the remaining code is small).
But when I call sceKernelNotifyCallback from inside a syscon debug handler, it again causes hardware malfunction. (Almost all sce* functions cause problems). Some times it shows no battery icon and shuts down, or it shows external power source, or screen starts flickering etc. (When such problem occurs it doesnt even go away with kernel reboot, or soft reset. Only cold boot will fix it.)
Only "normal" code without any external calls seems to work inside syscon debug handler.
The function is executing instantly (because the main thread is in DelayCB for most of the time anyway, the remaining code is small).
But when I call sceKernelNotifyCallback from inside a syscon debug handler, it again causes hardware malfunction. (Almost all sce* functions cause problems). Some times it shows no battery icon and shuts down, or it shows external power source, or screen starts flickering etc. (When such problem occurs it doesnt even go away with kernel reboot, or soft reset. Only cold boot will fix it.)
Only "normal" code without any external calls seems to work inside syscon debug handler.
Its for Hold+. I'm using the syscon_debug_handler to read the keys while the Hold switch is enabled.TyRaNiD wrote:I would ask what on earth you are doing, but then I realised you have no idea what you are doing so I can't be bothered to give you a sensible answer :)
The problem is when I need to react to those keys, I can't call any useful functions from inside that function without screwing up the PSP, thats why I have to execute them from another thread.
If this sounded confusing, what I meant was, once the main thread is waiting in the sceKernelDelayThreadCB, when I notify callback from the syscon_ctrl function, the callback is executed instantly without any delay.Torch wrote:The function is executing instantly (because the main thread is in DelayCB for most of the time anyway, the remaining code is small).
Last edited by Torch on Tue Feb 03, 2009 2:11 am, edited 3 times in total.
Inside this function...
As you can see, the syscon_ctrl function isn't exactly running in a second thread by started by me, I just said it was in the first post to prevent confusion due to ppl not knowing what syscon debug handler was, but its pretty much the same analogy because syscon_ctrl must be executing in some other thread started by the OS.
Code: Select all
sceSysconSetDebugHandlers(&syscon_debug_callbacks); // register on app start
......
static sceSysconDebugHandlers syscon_debug_callbacks =
{
syscon_debug_callback0,
syscon_transmit_callback,
syscon_receive_callback,
syscon_debug_callback3
};
void syscon_ctrl(sceSysconPacket *packet) // most sce* functions don't work properly inside this for obvious reasons.
{
newButtons=0;
rxd = packet->rx_data;
raw_ctrl.Lx = 0;
raw_ctrl.Ly = 0;
switch(packet->rx_response)
{
case 0x08:
raw_ctrl.Lx = rxd[4];
raw_ctrl.Ly = rxd[5];
goto SkipSetAnalog;
case 0x07:
.....
}
Well sceKernelNotifyCallback is causing malfunctions like I mentioned before. I didn't know about EventFlags functions, I'll try it now and hope it also doesn't screw up.TyRaNiD wrote:Unfortunately really the best you can have is sceKernelNotifyCallback as it is able to be called in an interrupt context (which I assume this is). If that is still screwing things up, well it is difficult :) You could try EventFlags but not sure that is going to significantly help you.
BTW I was wondering how much of a performance overhead this is consuming by calling this debug handler interrupt (atleast 60 times a second for the controller packets alone, it must call and return immediately much more often for other packet types)? I don't notice any slowdown in games though.
I'm not totally sure but EventFlags is like global variabiles, there's no way to send a "immediate request" to another thread, there's sceKernelPollEventFlag or sceKernelWaitEventFlag, but is the same thing as:
I don't know very well what are you doing, but can't you use another thread with less delay time? Or can be a problem during gameplay?
I've never made a plugin so ...
Code: Select all
if(global_var == value)
[...]
OR
while(global_var != value); // Probably with some delay
I've never made a plugin so ...
Get Xplora!
I wasn't able to get event flags working properly.
Is there anything special I have to do while using sceKernelNotifyCallback from an interrupt context? Sometimes it works, but during some games (specifically God of War) it causes an instant crash (full power off, no led, no display, and an audible pop from the speakers).
Is there anything special I have to do while using sceKernelNotifyCallback from an interrupt context? Sometimes it works, but during some games (specifically God of War) it causes an instant crash (full power off, no led, no display, and an audible pop from the speakers).