sleep or delay function help

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
EclipseOS

sleep or delay function help

Post by EclipseOS »

Hey
I have a sleep code that works fine on my 486 test computer, but when I try it on my athlon xp 2000+ (1667 mhz) it doesn't delay the full, 10 or 5 seconds or watever I tell it to wait.

here's my delay code:

void delay(int secs)
{
int x;
while (secs--)
{
x = bios_call(0);
while (bios_call(0) == x);
}
return;
}


inline static unsigned short bios_call(int data_a)
{
int data_b;
outportb(0x70, data_a);
data_b = inportb(0x71);
return data_b;
}
#endif

I want to know if my delay function works so that I can try and figure out a way to use it to find the cpu speed.

Thanx
DennisCGc

Re:sleep or delay function help

Post by DennisCGc »

I want to know if my delay function works so that I can try and figure out a way to use it to find the cpu speed.
It should work, I think ;)
There was a whole thread about this, but see the OSFaq.

HTH
Ozguxxx

Re:sleep or delay function help

Post by Ozguxxx »

I did not really konw aobut port 70 but is your time granularity same in both computers, I mean do you program pit or any other timer so that your are counting for same and correct granularity?
DennisCGc

Re:sleep or delay function help

Post by DennisCGc »

Ozgunh82 wrote: I did not really konw aobut port 70 but is your time granularity same in both computers, I mean do you program pit or any other timer so that your are counting for same and correct granularity?
Port 0x70 is used for the RTC.
EclipseOS

Re:sleep or delay function help

Post by EclipseOS »

I am grabbing the seconds from the RTC (0x70, 0x00) and using them to time a delay. I've used the RTC to make a time function that tells the time and it works fine on both computers. So if this won't work, what else could I do for a sleep() function? Thanx for your replys.
DennisCGc

Re:sleep or delay function help

Post by DennisCGc »

EclipseOS wrote: I am grabbing the seconds from the RTC (0x70, 0x00) and using them to time a delay. I've used the RTC to make a time function that tells the time and it works fine on both computers. So if this won't work, what else could I do for a sleep() function? Thanx for your replys.
Try using the timer interrupt instead.
Normal, it's programmed that it's called 18.2 times a second, but you can reprogram the PIT to reset that ;D
EclipseOS

Re:sleep or delay function help

Post by EclipseOS »

What is a PIT and what does it do? (Sorry, I'm new at this)
How do I program a timer interrupt? I know that u use IRQ 0, but I'm not exactly sure how. I do better at understanding things if I can have a piece of code to look at that is not too complicated. Thanx
DennisCGc

Re:sleep or delay function help

Post by DennisCGc »

PIT=Programmable Interrupt Timer, this chip calls the IRQ0 routine.
What you put in that routine, is totally up to you.
You can have a look at http://www.execpc.com/~geezer , or do a good search on this board, there are a lot of this related questions ;) (maybe in the FAQ ??? )

HTH, DennisCGc.
EclipseOS

Re:sleep or delay function help

Post by EclipseOS »

Finially got it to work right. It works the same on both computers now.Thanx for your help. Now how can I use sleep(int sec) to detect CPU speed? I looked at the FAQ and lots of other places, but I couldn't get it to work right. Anyone who has a working code, could you please show me an example? C or C++ code would be appreciated, thanx again.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:sleep or delay function help

Post by Pype.Clicker »

doesn't the good old

Code: Select all

    delay(1);
    long long before=rdtsc();
    delay(1);
    long long after=rdtsc();
    long mhz = (after-before) / 1000000;
work ?

(well, there are little chance it will since (long long)/(long) may require a math library if the compiler doesn't see it can do it without ...)
EclipseOS

Re:sleep or delay function help

Post by EclipseOS »

what does rdtsc() do? Like I've seen that piece of code many times before I just don't know what the rdtsc contains.
Curufir

Re:sleep or delay function help

Post by Curufir »

The Pentium-Pro (And above) contain a counter which increments for every processor cycle. The RDTSC instruction reads this 64-bit value (It gets returned in 2 registers, EDX and EAX I seem to recall). Once you know how many cycles pass in a specific time working out the frequency becomes trivial.
EclipseOS

Re:sleep or delay function help

Post by EclipseOS »

ya, but what I want is:

void rdtsc()
{
....
}
virusx

Re:sleep or delay function help

Post by virusx »

if you are using gcc.

Code: Select all

void  rdtsc()
{
      unsigned int slow, shigh;
      unsigned int elow, ehigh;
      unsigned long long start=0, end=0, result;
asm(
                "rdtsc\t\n"
                :"=a"(slow), "=d"(shigh)
                :
          );
      
sleep(1); /* in secs */

asm(
                "rdtsc\t\n"
                :"=a"(elow), "=d"(ehigh)
                :
          );
      start |= shigh;
      start <<= 32;
      start |= slow;

      end |= ehigh;
      end <<= 32;
      end |= elow;

      result = ((end - start)/1)/1000000;
      printf("%ld MHZ\n",result);

}
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:sleep or delay function help

Post by Candy »

Code: Select all

void  rdtsc()
{
      union {
          struct {
              unsigned int low, high;
          } split;
          unsigned long long total;
      } start = 0, end = 0;
      unsigned int result;

asm(
                "rdtsc\t\n"
                :"=a"(start.split.low), "=d"(start.split.high)
                :
          );
      
sleep(1); /* in secs */

asm(
                "rdtsc\t\n"
                :"=a"(end.split.low), "=d"(end.split.high)
                :
          );

      result = ((end - start)/1)/1000000;
      printf("%ld MHZ\n",result);

}
if you're using GCC anyway... ;)
Post Reply