Page 1 of 1

sleep(seconds/milliseconds) ?

Posted: Mon Jan 12, 2009 12:31 pm
by LBGSHI
Is there a function with PS2SDK, similar to sleep, that will allow me to create a delay that DOESN'T depend on the processor's clock cycles, but instead on the PS2's internal clock?

Posted: Mon Jan 12, 2009 12:56 pm
by ragnarok2040
I don't think there is. You could use the timed delay functions from http://forums.ps2dev.org/viewtopic.php?t=2842 pretty easily. uLE also uses a timer that uses T0.

Posted: Mon Jan 12, 2009 2:22 pm
by radad
Is there a function with PS2SDK, similar to sleep, that will allow me to create a delay that DOESN'T depend on the processor's clock cycles, but instead on the PS2's internal clock?
Whats the difference there? I dont think the EE has an internal clock. It does have internal timers. I have recently implemented the clock() function and plan to check it in soon. I was then going to look at a sleep() function, prefereably one that uses signals and interrupts rather than busy waits.

Posted: Mon Jan 12, 2009 3:27 pm
by LBGSHI
ragnarok2040: Yes, I had JUST found that when I checked back here, and saw your post :) Thanks; I'll dig through that. It looks like it should suffice.

radad: Cool; let us all know when you've uploaded it (or added it to the SVN?).

I just need a reliable timing system, and depending entirely on clock cycles or graphic refreshes seems inefficient, and, well...unreliable, heh.

I'll check into that thread, however. It looks to be promising. Thanks for the help, guys.

Posted: Mon Jan 12, 2009 7:53 pm
by radad
I have added my implemention of clock() to SVN: http://svn.ps2dev.org/listing.php?repna ... =1505&sc=0.

You could use this to write a crude sleep:

Code: Select all

unisgned int sleep(unisgned int secs)
{
    clock_t w = clock() + secs * CLOCKS_PER_SEC;
    
    while &#40;clock&#40;&#41; < w&#41;
        ;

    return 0;
&#125;
It uses EE timer 1 by default. EE timer 0 is been used by the profiling code. Timers are a rare resource so this may need to managed better in the future if there are more needs.

I did a small test to see if you could add two interrupt handlers for the same interrupt but it didnt seem to work. I was hoping because they get their own id the kernel would manage the chaining of them. There is also a 'next' parameter in the add interrupt call that I thought might be a way chaining them but that didnt work either.

Posted: Mon Jan 12, 2009 8:08 pm
by Lukasz
radad wrote:There is also a 'next' parameter in the add interrupt call that I thought might be a way chaining them but that didnt work either.
I seem to recall that if you pass 0 as the 'next' parameter the handler set as the first handler in the chain, if you pass -1 the handler is added at the end of the chain of interrupt handlers.

Code: Select all

AddIntcHandler&#40;INTC_XXX, handler1, 0&#41; <- first
AddIntcHandler&#40;INTC_XXX, handler2, -1&#41; <- second
AddIntcHandler&#40;INTC_XXX, handler3, -1&#41; <- third 

Posted: Mon Jan 12, 2009 9:12 pm
by radad
So if you pass 0 as the 'next' parameters does that wipe out the existing chain?

I have implemented the sleep() function now: http://svn.ps2dev.org/listing.php?repna ... =1506&sc=0

It uses a semaphore to block on and sets up an alarm to periodically check. What I wasnt sure of was what period to check. To get higher accuracy you want to check more often but you dont want to overload the cpu just with the checking. I settled on 600 H-SYNCs, so it is slightly different on PAL vs NTSC but I dont think it should matter.

Posted: Mon Jan 12, 2009 9:45 pm
by Lukasz
radad wrote:So if you pass 0 as the 'next' parameters does that wipe out the existing chain?
Not sure, you would need to test :-)

Posted: Tue Jan 13, 2009 3:48 am
by LBGSHI
Cool, good info :)

Thanks for committing it; I'll start testing it out soon, and implement it in my code.

Posted: Tue Jan 13, 2009 1:44 pm
by LBGSHI
radad: After grabbing those files and placing them in the libc directory of ps2sdksrc, in their proper places, I tried to compile libc, but got the error:

Code: Select all

src/unistd.c&#58; In function `sleep'&#58;
src/unistd.c&#58;88&#58; `CLOCKS_PER_SEC' undeclared &#40;first use in this function&#41;
src/unistd.c&#58;88&#58; &#40;Each undeclared identifier is reported only once
src/unistd.c&#58;88&#58; for each function it appears in.&#41;
make&#58; *** &#91;obj/sleep.o&#93; Error 1
I only see CLOCKS_PER_SEC mentioned in the clock test, so I'm guessing you forgot to declare this?

Posted: Tue Jan 13, 2009 1:56 pm
by radad
When I click on the links above it doesnt take it to the correct page due to the way it is embedding the '&' character in them.

Anyway it looks like you didnt grab all of the rev 1505 changes. CLOCKS_PER_SEC is deinfed in ps2sdk/ee/libc/include/time.h

Posted: Tue Jan 13, 2009 10:34 pm
by LBGSHI
Ah; fixed. Thanks.

Just to be sure, all I need to do to update now is to copy and paste libc.a and libc.erl into ps2dev\ps2sdk\ee\lib , correct?

Posted: Wed Jan 14, 2009 6:48 am
by radad
You have to copy the headers as well. I find it easiest to do a 'make release', that way you dont forget anything. Make sure do that at the top level in your 'ps2sdk' checkout or at least in 'ps2sdk/common', 'ps2sdk/ee/kernel' and 'ps2sdk/ee/libc'.

Posted: Wed Jan 14, 2009 9:42 am
by LBGSHI
Ah, OK. For now, I just copied everything inside libc/include to ps2sdk/ee/include. I'll keep make release in mind next time.

I've tried tossing together a simple test of this sleep function, but it doesn't seem to be working as planned. Perhaps you can point out my mistake faster than I can find it myself...

Code: Select all

#include <tamtypes.h>
#include <kernel.h>
#include <sifrpc.h>
#include <stdio.h>
#include <debug.h>
#include <time.h>

   unsigned int sleep&#40;unsigned int secs&#41;
&#123;
	
    clock_t w = clock&#40;&#41; + secs * CLOCKS_PER_SEC;
   
    while &#40;clock&#40;&#41; < w&#41;
        
    
    
    ;

    return 0;
&#125;

int main&#40;int argc, char *argv&#91;&#93;&#41;
&#123;
   SifInitRpc&#40;0&#41;;

   init_scr&#40;&#41;;

   scr_printf&#40;"test!\n"&#41;;

   sleep&#40;10&#41;;

   scr_printf&#40;"Hello, world!\n"&#41;;
   printf&#40;"Hello, world!\n"&#41;;
   
   while&#40;1&#41; &#123;&#125;
   
   return 0;
&#125;
Once it prints "test!" to the screen, it stops, forever. I'll tinker around with it, but a nudge in the right direction would be greatly appreciated.

Posted: Wed Jan 14, 2009 9:55 am
by radad
sleep() is in the ps2sdk as well so you dont need to use that version anymore. Anyway didnt you get a duplicate definition warning?

You may have the issue with the libc init I mentioned in the crt0 thread. Try printing out clock() before you call sleep:

Code: Select all

printf&#40;"clock&#58; %d\n", &#40;int&#41; clock&#40;&#41;&#41;;
If this prints zero then libc wasnt initialized.

Posted: Wed Jan 14, 2009 10:02 am
by LBGSHI
Indeed, it returns 0 (which means clock will always be less than w, unless w == 0). I'm not exactly following the solution in that thread. What would I need to do to either...

a. Call libc, which would at least allow it to work for the moment, or

b. Actually fix the problem in PS2SDK?

Posted: Wed Jan 14, 2009 10:09 am
by radad
The easiest way just to get clock working is to call:

Code: Select all

void _ps2sdk_time_init&#40;void&#41;;
It wont hurt if it is called twice, just resets clock() to zero.

The real fix is a new crt0.s but its not checked in yet.

Posted: Wed Jan 14, 2009 10:21 am
by LBGSHI
Adding void _ps2sdk_time_init(void); doesn't seem to fix the problem (I've declared it above main(), but I've also tried it within main(), and within the little sleep() function)...

So you've created a new crt0.s, but it's not up yet? I'll be eagerly awaiting it.

Posted: Wed Jan 14, 2009 10:27 am
by radad
You need to call it too:

Code: Select all

void _ps2sdk_time_init&#40;void&#41;;
....

int main&#40;int argc, char *argv&#91;&#93;&#41;
&#123;
   _ps2sdk_time_init&#40;&#41;;
   SifInitRpc&#40;0&#41;;
....


Posted: Wed Jan 14, 2009 10:34 am
by LBGSHI
I see. However, I'm still returning 0 for clock, and halting thereafter:

Code: Select all

#include <tamtypes.h>
#include <kernel.h>
#include <sifrpc.h>
#include <stdio.h>
#include <debug.h>
#include <time.h>

   
    unsigned int sleep&#40;unsigned int secs&#41;
&#123;
	
    clock_t w = clock&#40;&#41; + secs * CLOCKS_PER_SEC;
   
    while &#40;clock&#40;&#41; < w&#41;
        
   ;

    return 0;
&#125;

void _ps2sdk_time_init&#40;void&#41;;

int main&#40;int argc, char *argv&#91;&#93;&#41;
&#123;
   _ps2sdk_time_init&#40;&#41;;
   SifInitRpc&#40;0&#41;;

   init_scr&#40;&#41;;

   


   scr_printf&#40;"test!\n"&#41;;
   scr_printf&#40;"clock&#58; %d\n", &#40;int&#41; clock&#40;&#41;&#41;;
   
   sleep&#40;1&#41;;
   
   scr_printf&#40;"Hello, world!\n"&#41;;
   
   while&#40;1&#41; &#123;&#125;
   
   return 0;
&#125;
Thanks for being patient. I'm still fairly new to C, and PS2Dev, though I'm a relatively fast learner, considering the limited amount of free time I have.

Posted: Wed Jan 14, 2009 10:48 am
by radad
I dont know then. Do you get any warnings or errors from the compilation? Do the regression tests in libc work (again they wont until you get the new crt0.s)? This is probably going to be too hard for me to work out whats wrong remotely you will need to look further into this yourself.

Posted: Wed Jan 14, 2009 2:18 pm
by LBGSHI
I get no warnings nor errors, and the regress tests compile properly, but seem to do nothing (I haven't really taken a look to see if they're supposed to output anything, so perhaps they're functioning as planned).

I'll spend some time pieces everything apart, and see if I can figure out the problem. Thanks for your help, and let me know when you check the new crt0.s in.

Posted: Thu Jan 15, 2009 3:21 pm
by ragnarok2040
I tested out your problem LBGSHI and it's definitely the crt0.s. Your code works fine with the new one. If you want to try out the new crt0.s, I separated my latest changes into separate patches.

http://forums.ps2dev.org/viewtopic.php?t=11546#78544

To apply:

Code: Select all

patch -p0 < crt0.patch
or

Code: Select all

cat crt0.patch | patch -p0
while you're in the root directory of ps2sdk's src or $PS2SDKSRC directory.