Is there a delay which yields?

Scott Long scottl at samsco.org
Thu Mar 19 16:06:13 PDT 2009


Barney Cordoba wrote:
> 
> 
> 
> --- On Thu, 3/19/09, John Baldwin <jhb at freebsd.org> wrote:
> 
>> From: John Baldwin <jhb at freebsd.org>
>> Subject: Re: Is there a delay which yields?
>> To: freebsd-current at freebsd.org, barney_cordoba at yahoo.com
>> Cc: "Julian Elischer" <julian at elischer.org>, current at freebsd.org
>> Date: Thursday, March 19, 2009, 11:23 AM
>> On Sunday 15 March 2009 2:43:18 pm Barney Cordoba wrote:
>>> --- On Sun, 3/15/09, Julian Elischer
>> <julian at elischer.org> wrote:
>>>> From: Julian Elischer <julian at elischer.org>
>>>> Subject: Re: Is there a delay which yields?
>>>> To: barney_cordoba at yahoo.com
>>>> Cc: current at freebsd.org
>>>> Date: Sunday, March 15, 2009, 1:16 PM
>>>> Barney Cordoba wrote:
>>>>> I'd expect DELAY to yield till timeout
>> but a task
>>>> with a delay loop just
>>>>> runs to 100% usage. Is there a function
>> which can
>>>> yield exectution for
>>>>> a set amount of time (without having to use
>> a timer)?
>>>> DELAY is designe for use early in the boot when
>> thre are no
>>>> timers.
>>>> it is only occasionally used for cases during
>> normal
>>>> operation.
>>>>
>>>> how would a thread know how long it has been away
>> if no
>>>> timer is used?
>>>
>>> I guess I mean a sleep. 
>>>
>>> Also, this is a kernel driver. I have a device
>>> which requires a toggle with a 10ms delay between
>> pulses. I hate to 
>>> tie up the cpu for 10ms with a delay. Sort of like the
>> following:
>>> write_pulse();
>>> delay(10000);
>>> write_pulse();
>> Use pause(9).
>>
> 
> timo is in hz? So 1/1000th of a second by default?

No, hz is variable.  The expression "timo * hz" will give
you a sleep of 'timo' number of seconds.  The expression
"time * hz / 1000" will give you a sleep of 'timo' number of
milliseconds.  Resolution under 10ms is not guaranteed, though
that conventional wisdom is from the days when hz was 100 and
might not be as strict with hz=1000.  But again, you can't
assume that you know the value of hz.  The symbol 'hz' is global
in the kernel and available from the standard kernel header files.
This is all explained in the pause.9 man page.

> 
> Also, I notice that hz is 1000 but get 2000 ints/second per
> cpu. Why is it twice hz?

The cpu timer is divided down to 3 timers: hz, stathz, and profhz.
These tree timer frequencies need to be as dissimilar as possible so
they don't develop a beat frequency between them.  Having the cpu timer
be significantly higher than hz makes it easier to choose good divisors
for the other frequencies.  The value is of the cpu timer is based off
of the desired value of hz, but sometimes is not 2x.  For example, if
you set kern.hz=100, the cpu timer will be 400.  This allows for
sufficient resolution of profhz.

There's something to be said for going back to single stathz and
profhz timers, instead of having every CPU run at a high interrupt
rate to track them.  Fixing that is likely hard, what is easier is
to just set kern.hz=100.  With kernel preemption, having a high
scheduler resolution isn't as critical is it was once thought to be.

Scott


More information about the freebsd-current mailing list