Re: sched_yield() problems...
From: Regis Cattenoz (cattenoz.regis_at_wanadoo.fr)
Date: 02/28/05
- Previous message: General Schvantzkoph: "Re: RH Linux 8 w/ SATA"
- In reply to: Frank Rudolph: "sched_yield() problems..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
>
>
>
>
- Previous message: General Schvantzkoph: "Re: RH Linux 8 w/ SATA"
- In reply to: Frank Rudolph: "sched_yield() problems..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|