Try to understand eventing on PSP (sceKernelWaitEventFlag)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
anmabagima
Posts: 87
Joined: Thu Oct 01, 2009 8:43 pm

Try to understand eventing on PSP (sceKernelWaitEventFlag)

Post by anmabagima »

Hi there,

I try to use PSP events to controll threads. However, I've created a thread that uses sceKernelWaitEventFlag to wait for a certain event. However, in the mainthread I'm setting the event flag pattern with sceKernelSetEventFlag only once. But the thread again and again recieves the same eventflag bit pattern.

Are the flags cleared somehow ? I've tryied the flag PSP_EVENT_WAITCLEAR, tried sceKernelClearEventFlag but nothing seem to work. What ever flags I'm subsequently setting the sceKernelWaitEventFlag seem to recieve only the first send bit flags.

Is there something like a queue where I'm only waiting for the first entry and have missed to signal that I've processed the event ?

Any hint was much appreachiated...

The goal of this activity would be: signal from the main thread to the new thread that it should clean up and finish working or that it should toggle some kind of performing stuff...

Thanks in advance..
User avatar
Coldbird
Posts: 97
Joined: Thu Feb 08, 2007 7:22 am

Post by Coldbird »

You could achieve the same thing you want using Semaphores / Mutexes.

(Mutexes aren't documented in the PSPSDK... but the PSP is capable of producing and using them via undocumented functions, so stick to Semaphores...)

I must admit I never touched Event Flags myself, I only triggered some using some dirty hacks for some fw hacks I've done...
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Re: Try to understand eventing on PSP (sceKernelWaitEventFla

Post by Raphael »

anmabagima wrote:Hi there,

Are the flags cleared somehow ? I've tryied the flag PSP_EVENT_WAITCLEAR, tried sceKernelClearEventFlag but nothing seem to work.
Yes, PSP_EVENT_WAITCLEAR will clear all bits in the event flag that matched when checking.
I guess your problem is more towards how you actually check for the event flag (WAITOR, WAITAND).
The goal of this activity would be: signal from the main thread to the new thread that it should clean up and finish working or that it should toggle some kind of performing stuff...
If that is the only goal, ie a single signal for one thread to start/stop working, then semaphores are the more fitting choice. An event flag is better for signalling a thread multiple states at once (I used it for my mp3 routines to signal which of the buffers were full/empty).

The basic flow for your case handled with event flags would be like this:

Code: Select all

create event flag
set event flag to 0

in main thread, when thread 2 should be triggered:
sceKernelSetEventFlag(evid, 0x1);

thread 2:
while (running) {
sceKernelWaitEventFlag(evid, 0x1, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout);
... do the work ...
}
Here, waitor means that it will activate whenever bit 0 is set, no matter the other bits in the flag.
Waitand on the other hand would only active if the bit mattern exactly matches the value 0x1 and not if the event flag would be 0x1001 for example.
If you want, I can look for my mp3 code when I get home, to get sure how it worked (iirc I also used sceKernelClearEventFlag somewhere).
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
anmabagima
Posts: 87
Joined: Thu Oct 01, 2009 8:43 pm

Post by anmabagima »

Hi,

thanks for your hints Raphael. I'm also trying to use it for my MP3 playing thread but not only for start/stop but for adjusting volume eg. While the mainthread eg. is moving from menu state to load a level the currently playing background music should go smooth to mute.

Therefore I'm setting the eventflag at eg. Bit 2 to 1 signal I want to change volume and mask the highword bits with the volume. However, if do something like this:

Code: Select all

for &#40;int i=0x800;i>0;i-=0x100&#41;&#123;
  sceKernelSetEventFlag&#40;evid, 0x2 | i <<16&#41;;
&#125; 
and in the thread than:

Code: Select all

while &#40;running&#41; &#123;
sceKernelWaitEventFlag&#40;evid, 0x2, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout&#41;; 
if &#40;bits & 0x2&#41;&#123;
 volume = bits >> 16;
&#125;
&#125;
each time the result in bits is always the same and only matches to the first call of sceKernelSetEventFlag, therefore the volume is always the same :( . May be I'm a bit noob or stupid, however I will investigate on semaphore as well. May be that they work.
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

look at this topic http://forums.ps2dev.org/viewtopic.php? ... ht=library
it is a complete implementation of posix pthread for the psp
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

anmabagima wrote: Therefore I'm setting the eventflag at eg. Bit 2 to 1 signal I want to change volume and mask the highword bits with the volume. However, if do something like this:

Code: Select all

for &#40;int i=0x800;i>0;i-=0x100&#41;&#123;
  sceKernelSetEventFlag&#40;evid, 0x2 | i <<16&#41;;
&#125; 
Why do you run a loop to set the event flag? This will come out the same as just a single call to sceKernelSetEventFlag(evid, 0x2 | 0x100 <<16); in propably 99% of cases, because the waiting thread doesn't get a chance to do anything before the flag is overwritten by the next iteration.
Remember, the PSP has a non-preemptive aka cooperative threading model.
Normally, if you want to make sure that your other thread has got the event, you put a sceKernelWaitEventFlag and wait for either the 0x2 bit to be cleared or another bit be set. At least however, you should give the other thread some time to work, so a delaythread(0) or (1) could also do the trick.
and in the thread than:

Code: Select all

while &#40;running&#41; &#123;
sceKernelWaitEventFlag&#40;evid, 0x2, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout&#41;; 
if &#40;bits & 0x2&#41;&#123;
 volume = bits >> 16;
&#125;
&#125;
Well, apart from the fact that you don't really have to check if bits 0x2 is set, this code is good.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
anmabagima
Posts: 87
Joined: Thu Oct 01, 2009 8:43 pm

Post by anmabagima »

Hi Raphael,

thanks. The iteration is pretty much simplyfied and off course the main thread does some delays before setting the event flag again. The reason for doing this in a "loop" is that I try to fade the music out in decreasing the volume. However, during writing this post I just imagine there could be an other approach ;o) Just signal to the play thread that I want to fade out and then do this complete there.

However, I've also tried to set the eventflag only once in my mainthread, but the additional thread - running the loop - recieves the eventflag again and again unless if I'm clearing the flag or not.


As example:
Mainthread -

Code: Select all

sceKernelSetEventFlag&#40;evid, 0x2 | 0x500 <<16&#41;; 
MP3 Thread:

Code: Select all

while &#40;running&#41; &#123; 
sceKernelWaitEventFlag&#40;evid, 0x2, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout&#41;; 
if &#40;bits & 0x2&#41;&#123; 
//this is true at each iteration, regardless of clearing this 
//or not bits =0; does not help either
 volume = bits >> 16; 
&#125; 
&#125;
within the mp3 thread the eventflag is recieved during each loop. is this as it should work or is there an error ? I've tried to clear the eventflag as well. It does not seem to work....

In addition I'm checking for with (bits & 0x2) hat the flag is really recieved and not just reached the timeout...I have assumed that bits would be 0 if the timeout for waiting is reached...
Post Reply