Discussion:
pause_ms() wrapper
John Baldwin
2016-09-02 19:22:42 UTC
Permalink
Figuring out the 3 arguments required for pause_sbt() can be a bit
non-obvious (at least to me). To that end, I'd like to have a simple
wrapper around pause_sbt() that accepts milliseconds. It would align
itself on hardclock similar to the hz-based wrapper. OTOH, we could
change the implementation at some point to use something more resaonable
in terms of precision, etc. However, most of the time when I want to
sleep for N milliseconds (or N microseconds) due to some hardware spec,
I don't really have a strong opinion on the precision. Having all the
callers try to figure out a precision would seem to inevitably result
in inconsistencies. To start with I'd like to just add this:

#define pause_ms(wmesg, msecs) \
pause_sbt((wmesg), SBT_1MS * (msecs), 0, C_HARDCLOCK)

Which you can use as 'pause_ms("pcieflr", 100);'.

Are there any objections? Do people want other wrappers? Should we
use more nuanced math similar to what was done in r296775?
--
John Baldwin
Adrian Chadd
2016-09-03 02:32:56 UTC
Permalink
Can we please name it something that indicates it's not designed to be exact?

The .. exactness of various calls has been a thorn in the side of a
few people, myself included. I've been bitten by the callout precision
changes :(

I like linux's usleep_range() for example. It makes it obvious that
you can get anything inside that bar. How hard is that to do with
pause_sbt() ?


-adrian
Post by John Baldwin
Figuring out the 3 arguments required for pause_sbt() can be a bit
non-obvious (at least to me). To that end, I'd like to have a simple
wrapper around pause_sbt() that accepts milliseconds. It would align
itself on hardclock similar to the hz-based wrapper. OTOH, we could
change the implementation at some point to use something more resaonable
in terms of precision, etc. However, most of the time when I want to
sleep for N milliseconds (or N microseconds) due to some hardware spec,
I don't really have a strong opinion on the precision. Having all the
callers try to figure out a precision would seem to inevitably result
#define pause_ms(wmesg, msecs) \
pause_sbt((wmesg), SBT_1MS * (msecs), 0, C_HARDCLOCK)
Which you can use as 'pause_ms("pcieflr", 100);'.
Are there any objections? Do people want other wrappers? Should we
use more nuanced math similar to what was done in r296775?
--
John Baldwin
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
Bruce Evans
2016-09-03 06:41:58 UTC
Permalink
Post by John Baldwin
Figuring out the 3 arguments required for pause_sbt() can be a bit
non-obvious (at least to me). To that end, I'd like to have a simple
wrapper around pause_sbt() that accepts milliseconds. It would align
itself on hardclock similar to the hz-based wrapper. OTOH, we could
change the implementation at some point to use something more resaonable
in terms of precision, etc. However, most of the time when I want to
sleep for N milliseconds (or N microseconds) due to some hardware spec,
I don't really have a strong opinion on the precision. Having all the
callers try to figure out a precision would seem to inevitably result
I complained to mav about the difficult of controlling precision. The
defaults work poorly. There are too many too complicated options to
override the defaults, but not enough not complicated enough to do what
I want. E.g., the 5% default error is too large for long timeouts,
but there is no way to reduce it for long timeouts -- the options only
allow you to increase it further.
Post by John Baldwin
#define pause_ms(wmesg, msecs) \
pause_sbt((wmesg), SBT_1MS * (msecs), 0, C_HARDCLOCK)
Here C_HARDCLOCK is supposed to give compatibility with old periodic
hardclock. It doesn't do that. With a requested timeout of n ticks,
old periodic hardclock gives a timeout of 1 fractional ticks (average
1/2) and n-1 full ticks and it was possible to sync with or predict
when the ticks would occur and adjust n up or down by 1 to compenstae
the fractional tick. C_HARDCLOCK with a requested timeout of n ticks
gives a timeout of at least n ticks, extended by the system's best attempt
to not much more than N%, where N defaults to 5 but can be changed by the
sysadmin. This magic 5 and the sysctl are not documented in any man page.

Often, 5% is much more accuracy that needed, but asking for less is
even more complicated than asking for more. First you have to do
something to avoid the default having precedence. For some APIs,
C_HARDCLOCK is the default 'flags' is 0, so you have to use C_PREL()
to avoid it. C_PREL(32) gives a tiny percentages so allows the 'pr'
parameter (0 here) to dominate. The 2 precision parameters mostly
give complications by getting in each other's way.
Post by John Baldwin
Which you can use as 'pause_ms("pcieflr", 100);'.
Are there any objections? Do people want other wrappers? Should we
use more nuanced math similar to what was done in r296775?
There should also be a wrapper for the usual case of setting up a callout,
with a good name like "timeout". callout_reset() was already too
complicated and badly named (it is more related to times than calls,
and more related to [re]starting than resetting (clearing)). But it is
trivial compared with callout_reset_sbt_on().

I don't actually like the macro. Most callout functions are already
macros several layers deep leading to callout_reset_sbt_on(). This
was painful to debug with ddb.

r296775 has no effect for most uses. The error is usually 5%. I think
sloppiness on the old scaling usually gave much smaller errors.

Bruce

Loading...