svn commit: r280674 - user/dchagin/lemul/sys/compat/linux
Dmitry Chagin
dchagin at freebsd.org
Thu Mar 26 12:30:37 UTC 2015
2015-03-26 10:43 GMT+03:00 Bruce Evans <brde at optusnet.com.au>:
> On Thu, 26 Mar 2015, Dmitry Chagin wrote:
>
> Log:
>> Linux nanosleep() and clock_nanosleep() system calls always
>> writes the remaining time into the structure pointed to by rmtp
>> unless rmtp is NULL. The value of *rmtp can then be used to call
>> nanosleep() again and complete the specified pause if the previous
>> call was interrupted.
>>
>> Note. clock_nanosleep() with an absolute time value does not write
>> the remaining time.
>>
>
> FreeBSD doesn't even have clock_nanosleep(). It also sleeps on a wrong
> clock id (CLOCK_MONOTONIC instead of CLOCK_REALTIME) in nanosleep().
> clock_nanosleep() exists mainly because CLOCK_REALTIME is usually the
> wrong clock to sleep on, but is the one specified for nanosleep() for
> historical reasons.
>
> It is stupid for the emulator to have clock_nanosleep() before the host
> system. The the emulator doesn't seem to have it either. It seems to
> just use the native nanosleep(), so sleeps on the wrong clock id for all
> except CLOCK_MONOTONIC.
>
I know, Bruce. This is (clock_nanosleep) 'yet another odd job' from netbsd.
Anyway, thanks for the explanation.
I would prefer to fix host system before emulator if someone point me
to the right direction.
>
> Modified: user/dchagin/lemul/sys/compat/linux/linux_time.c
>> ============================================================
>> ==================
>> --- user/dchagin/lemul/sys/compat/linux/linux_time.c Thu Mar 26
>> 06:00:42 2015 (r280673)
>> +++ user/dchagin/lemul/sys/compat/linux/linux_time.c Thu Mar 26
>> 06:36:34 2015 (r280674)
>> ...
>> @@ -490,25 +488,19 @@ linux_nanosleep(struct thread *td, struc
>> return (error);
>> }
>> error = kern_nanosleep(td, &rqts, rmtp);
>>
>
> The emulator could fix up cases where the sleep on the wrong clock is too
> short, by calculating the error and sleeping again. It doesn't do this,
> but if it just used the correct clock id for calculating the remaining
> time for the purpose of returning it, then it would know the time to
> sleep again (when there is no error but the remaining time is > 0).
>
> @@ -558,24 +550,19 @@ linux_clock_nanosleep(struct thread *td,
>> return (error);
>> }
>> error = kern_nanosleep(td, &rqts, rmtp);
>>
>
> Linux apparently uses the correct clock id for nanosleep(), since this
> function only tries to support that clock id (LINUX_CLOCK_REALTIME).
> The function has already returned EINVAL for other clock ids. But since
> FreeBSD nanosleep() is broken, the unique clock id that can be supported
> here is actually LINUX_CLOCK_MONOTONIC.
> Strictly, not even that. FreeBSD used to use getnanouptime() in
> nanosleep(), so nanosleep() only gave 1/HZ resolution. There is a
> clock id CLOCK_MONOTIC_FAST for this, so nanosleep() strictly only
> used that clock id, and if clock_nanosleep() were implemented then
> it should use getnanouptime() precisely when the caller uses this
> clock id.
>
> Presumably Linux doesn't have LINUX_CLOCK_MONOTONIC_FAST to map to
> the FreeBSD mistake CLOCK_MONOTONIC_FAST, so the best this function
> can do is map to CLOCK_MONOTONIC. Changing to this would probably
> break more than it fixes. Apparently, Linux software does use
> clock_nanosleep(), but with CLOCK_REALTIME, else the error for using
> it with CLOCK_MONOTIC would be noticed. clock_nanosleep() is not
> very useful without TIMER_ABSTIME since it is only a verbose spelling
> of nanosleep() then. It is useful with TIMER_ABSTIME, but that case
> is not supported. Perhaps the software uses clock_nanosleep() because
> it wants to use TIMER_ABSTIME someday when that is supported.
>
> Now, nanosleep() uses sbintimes so it isn't clear what clock id it
> sleeps on. The clock is still monotonic and not affected by leap
> seconds or suspensions. Its resolution seems to be much lower than
> 1/HZ even when HZ is 100. "sleep 1" often sleeps for 65 milliseconds
> extra on freefall, but shorter sleeps rarely sleep by more than 3
> milliseconds extra.
>
> - if (error != 0) {
>> - LIN_SDT_PROBE1(time, linux_clock_nanosleep,
>> nanosleep_error,
>> - error);
>> - LIN_SDT_PROBE1(time, linux_clock_nanosleep, return,
>> error);
>> - return (error);
>> - }
>> -
>> if (args->rmtp != NULL) {
>> + /* XXX. Not for TIMER_ABSTIME */
>>
>
> TIMER_ABSTIME has already been handled (by XXXing and returning an error).
>
> TIMER_ABSTIME is only very useful with CLOCK_REALTIME. It allows sleeping
> until a specified real time without being messed up by leap seconds and
> clock steps. For CLOCK_MONOTONIC, it is not even clear what an absolute
> time is. I think POSIX specifies CLOCK_MONOTONIC to increment in as
> clocks to physical seconds as it can, but in FreeBSD it stops incrementing
> during suspend.
>
> Bruce
>
More information about the svn-src-user
mailing list