| View previous topic :: View next topic |
| Author |
Message |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Mon Feb 02, 2009 1:33 pm Post subject: 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. |
|
| Back to top |
|
 |
jean

Joined: 05 Jan 2008 Posts: 489
|
Posted: Mon Feb 02, 2009 8:45 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Mon Feb 02, 2009 9:16 pm Post subject: |
|
|
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. |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Tue Feb 03, 2009 12:13 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Feb 03, 2009 12:27 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
TyRaNiD
Joined: 18 Jan 2004 Posts: 918
|
Posted: Tue Feb 03, 2009 1:29 am Post subject: |
|
|
| 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 :) |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Feb 03, 2009 1:36 am Post subject: |
|
|
| 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 :) |
Its for Hold+. I'm using the syscon_debug_handler to read the keys while the Hold switch is enabled.
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.
| 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). |
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.
Last edited by Torch on Tue Feb 03, 2009 2:11 am; edited 3 times in total |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Feb 03, 2009 1:43 am Post subject: |
|
|
Inside this function...
| Code: |
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:
.....
} |
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. |
|
| Back to top |
|
 |
ctszy
Joined: 12 Apr 2008 Posts: 18
|
Posted: Tue Feb 03, 2009 2:46 am Post subject: |
|
|
not sure though.. but seems Booster has done sth similar with yours?
just Google "vshex_syscon" and take a look :) |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Feb 03, 2009 2:48 am Post subject: |
|
|
| ctszy wrote: | not sure though.. but seems Booster has done sth similar with yours?
just Google "vshex_syscon" and take a look :) |
This IS based on booster's syscon debug sample. I've just cut down on the unnecessary things. |
|
| Back to top |
|
 |
TyRaNiD
Joined: 18 Jan 2004 Posts: 918
|
Posted: Tue Feb 03, 2009 4:55 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Feb 03, 2009 5:05 am Post subject: |
|
|
| 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. |
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.
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. |
|
| Back to top |
|
 |
ne0h
Joined: 21 Feb 2008 Posts: 386
|
Posted: Tue Feb 03, 2009 7:42 am Post subject: |
|
|
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:
| Code: |
if(global_var == value)
[...]
OR
while(global_var != value); // Probably with some delay
|
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 ... _________________ Get Xplora! |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Feb 03, 2009 7:58 am Post subject: |
|
|
Event flags has a wait timeout, so I guess its effectively the same as DelayThreadCB. If the event occurs while its waiting it will fire, other wise it goes to the next iteration and executes my other code first before waiting again.
I haven't tried it in my plugin yet to see if it screws up. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Feb 04, 2009 1:38 am Post subject: |
|
|
@TyRaNiD
I noticed you didn't read my PM. I assumed you read it first yesterday and then replied here about the EventFlags. It contains the source code of my plugin, so if you take a look at that it might help with some ideas. |
|
| Back to top |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Wed Feb 04, 2009 7:22 am Post subject: |
|
|
Is it not possible to have a high priority thread waiting on a semaphore. In your debug thread you raise the semaphore and yield. That should make the high priority thread run immediately.
Jim _________________ http://www.dbfinteractive.com |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Feb 04, 2009 7:24 am Post subject: |
|
|
I can't call the sema functions from the debug thread, it also malfunctions.
I'm yet to try the EventFlags, I'm away from my dev pc at the moment. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Thu Mar 12, 2009 3:32 pm Post subject: |
|
|
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). |
|
| Back to top |
|
 |
|