Re: sched_yield() problems...

From: Regis Cattenoz (cattenoz.regis_at_wanadoo.fr)
Date: 02/28/05

  • Next message: George: "Upgrading XFree86-lib on RH9 to 4.3.0-2 or better"
    Date: Mon, 28 Feb 2005 00:11:21 +0100
    
    

    Hi Franck.

    I was just playing a few day ago with posix thread. I don't get the
    exact same issues as you are, but I can try to suggest idea anyway.

    To timestamp the processing in my threaded application, I used the rdtsc
    register in the CPU core. This is a 64 bit register that count the clock
    cycle of the CPU. I get very good resolution here (sub ns with 2+GHz
    CPU), and when using sched_yield() to make less agressive active wait
    loop, I get reaction time of less than 10 us (As far as I remember).
    The reading of this register is quite easy to do.
    So it works fine for me.
    I just needed to also access the /proc/cpuinfo to get the CPU frequency
    to calibrate the tsc register results.

    Google should provide several reference ( for instance:
    http://pasta.east.isi.edu/algorithms/IntegerMath/Timers/ )
    // The basic function is :
    volatile unsigned long long RDTSC()
    {
       __asm__ volatile(".byte 0x0f,0x31");
    }

    You will have to do some 64 bit arithmetic to use results, nothing too
    difficult.
    Be aware than the portability is not at top here (asm may stuck you to a
    compiler, i.Egcc only), or Pentium type CPU (I succesfully access this
    register on P4 and AMD CPU also, so It is not really an issue).
    I get you have RHEL here (on x86 ?) so it may be OK

    So if this is ok for your need you can replace this gettimeofday() with
    rdtsc.
    In fact, I don't know why your gettimeofday don't work, so don't blame
    me for answering the wrong question, I just suggest possible alternative
    ;-).

    Hope this help.
    Regis.

    Frank Rudolph wrote:
    > I am working with RHEL 2.4.something and am having problems with scheduling
    > POSIX threads.
    > I want to have two simple threads trading the CPU back and forth as quickly
    > as possible.
    >
    > I need one of the threads to pause for 35 ms and the other to accurately
    > detect when a 2 second timer goes off and otherwise be on duty continuously.
    >
    > I want to avoid using usleep() because it is too coarse and is too
    > indeterminant. I can ask for as little as 10 millisecs, since ticks runs at
    > 100 Hz, but I never get anything close to that in reality. I can get 20
    > something millis with a great deal of variance and sometimes lose the CPU
    > for as long as 185 millis, this approach is no good.
    >
    > Since sched_yield() never actually puts the threads to sleep, the overhead
    > is significantly less. When I wrote my first test loops, I determined that I
    > could run loops that would come back on task in about 25 microseconds with
    > very little variation (I was delighted).
    >
    > Then I tried putting some of the actual code in the loops and used
    > gettimeofday to find the current time in seconds and microseconds so I could
    > poll time in the loop to detect timeouts. When I tried any variation on the
    > following loop. In the loop I check to see if the current time has exceeded
    > a limit I calculated earlier. If the limit is exceeded, I give up the CPU so
    > the other thread can do its thing, otherwise, I do some processing and
    > repeat.
    >
    > struct timeval t_now, t_end; // calculation of t_end not shown
    >
    > while (1) // this is a control system, so the loop runs forever
    > { gettimeofday(&t_now);
    > if (!compare_time(t_now,t_end)) // implementation of compare_time
    > not shown
    > if( !sched_yield())
    > { printf("\nsched_yield fils with errno = %d", errno);
    > exit(err_no);
    > }
    > else <do some processing>
    > }
    >
    > I got errno = 14 (invalid address)
    > If I ignored the error condition I got a segmentation error.
    >
    > If I coded loops that only called sched_yield() without checking the current
    > time, no errors occurred.
    >
    > Of course both threads implemented thise loop with some variations, so it
    > occurred to me that
    > maybe gettimeofday() was not reentrant? But I could find no information
    > about it to determine one way or the other if this were the case. If I knew
    > this to be the case, I could develop a workaround.
    > I hacked around with this for hours yesterday and finally decided I needed
    > to ask for some help!!!!
    >
    > I am also using mutex exclusion, and so on. The whole loop works flawlessly
    > when I let the two threads simply sleep for 20 or 35 ms. I just can't deal
    > with the uncertainty of the timing. And I really don't want to get an
    > embedded linux, because this project doesn't merit the effort.
    >
    > Anyone ever run into this problem before?
    >
    > - Frank
    >
    >
    >
    >


  • Next message: George: "Upgrading XFree86-lib on RH9 to 4.3.0-2 or better"

    Relevant Pages

    • Re: Cost of calling a standard library function
      ... It accesses/reads memory using esi 4 ... > safly move it within the cache, without having to go via ebx. ... try it the same thing on a different earlier CPU, ... should check it out...for "tight inner loop" stuff, ...
      (alt.lang.asm)
    • Re: Polling, Interrupts, DMA, Synchronous, Asynchronous I/O Definitions
      ... the terminology is less useful than it might be. ... though a "message loop" could arguably be claimed to be ... considering in a particular iteration but what is true for _ALL_ ... watching the "polling" version eating up every single CPU cycle ...
      (alt.lang.asm)
    • Re: getting a threads state and CPU utilization
      ... of CPU time currently being used)? ... How could you tell an infinite loop from a polling loop ... responding to continuous messages from many client apps, ... though the customer *claims* that the client app is disconnecting (I suspect ...
      (microsoft.public.win32.programmer.kernel)
    • Re: Detect the loop for batch job
      ... We are looking for a tool to detect the loop for batch application, ... step is to impose and enforce standards requiring reasonable CPU TIME ...
      (bit.listserv.ibm-main)
    • sched_yield() problems???????
      ... I want to have two simple threads trading the CPU back and forth as quickly ... very little variation. ... gettimeofday to find the current time in seconds and microseconds so I could ... poll time in the loop to detect timeouts. ...
      (alt.os.linux)