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..
Try to understand eventing on PSP (sceKernelWaitEventFlag)
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
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...
(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?
Re: Try to understand eventing on PSP (sceKernelWaitEventFla
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).
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 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...
The basic flow for your case handled with event flags would be like this:Here, waitor means that it will activate whenever bit 0 is set, no matter the other bits in the flag.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 ... }
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
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
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:
and in the thread than:
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.
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 (int i=0x800;i>0;i-=0x100){
sceKernelSetEventFlag(evid, 0x2 | i <<16);
}
Code: Select all
while (running) {
sceKernelWaitEventFlag(evid, 0x2, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout);
if (bits & 0x2){
volume = bits >> 16;
}
}
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
look at this topic http://forums.ps2dev.org/viewtopic.php? ... ht=library
it is a complete implementation of posix pthread for the psp
it is a complete implementation of posix pthread for the psp
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.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 (int i=0x800;i>0;i-=0x100){ sceKernelSetEventFlag(evid, 0x2 | i <<16); }
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.
Well, apart from the fact that you don't really have to check if bits 0x2 is set, this code is good.and in the thread than:Code: Select all
while (running) { sceKernelWaitEventFlag(evid, 0x2, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout); if (bits & 0x2){ volume = bits >> 16; } }
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 87
- Joined: Thu Oct 01, 2009 8:43 pm
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 -
MP3 Thread:
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...
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(evid, 0x2 | 0x500 <<16);
Code: Select all
while (running) {
sceKernelWaitEventFlag(evid, 0x2, PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR, &bits, &timeout);
if (bits & 0x2){
//this is true at each iteration, regardless of clearing this
//or not bits =0; does not help either
volume = bits >> 16;
}
}
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...