From b0040075af4a9da05aaae4c7ea06b4454c644344 Mon Sep 17 00:00:00 2001 From: Michael Kerrisk Date: Mon, 23 Jun 2008 09:41:18 +0000 Subject: [PATCH] Remove crufty discussion of HZ, and replace with a pointer to time(7). See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=485636 Replace mentions of "process' by "thread". NOTES: describe case where clock_nanosleep() can be preferable. NOTES: describe CLOCK_REALTIME versus CLOCK_NANOSLEEP See also http://thread.gmane.org/gmane.linux.kernel/696854/ "nanosleep() uses CLOCK_MONOTONIC, should be CLOCK_REALTIME?" Some minor rewrites. --- man2/nanosleep.2 | 119 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 35 deletions(-) diff --git a/man2/nanosleep.2 b/man2/nanosleep.2 index c19dfeb98..42ecf1975 100644 --- a/man2/nanosleep.2 +++ b/man2/nanosleep.2 @@ -1,6 +1,8 @@ .\" Hey Emacs! This file is -*- nroff -*- source. .\" .\" Copyright (C) Markus Kuhn, 1996 +.\" and Copyright (C) Linux Foundation, 2008, written by Michael Kerrisk +.\" .\" .\" This is free documentation; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License as @@ -25,9 +27,14 @@ .\" 1996-04-10 Markus Kuhn .\" First version written .\" Modified, 2004-10-24, aeb -.TH NANOSLEEP 2 2007-07-26 "Linux" "Linux Programmer's Manual" +.\" 2008-06-24, mtk +.\" Minor rewrites of some parts. +.\" NOTES: describe case where clock_nanosleep() can be preferable. +.\" NOTES: describe CLOCK_REALTIME versus CLOCK_NANOSLEEP +.\" Replace cruft discussion of HZ with a pointer tom time(7). +.TH NANOSLEEP 2 2008-06-24 "Linux" "Linux Programmer's Manual" .SH NAME -nanosleep \- pause execution for a specified time +nanosleep \- high-resolution sleep .SH SYNOPSIS .B #include .sp @@ -42,14 +49,18 @@ Feature Test Macro Requirements for glibc (see _POSIX_C_SOURCE\ >=\ 199309L .SH DESCRIPTION .BR nanosleep () -delays the execution of the program for at least the time specified in -.IR *req . -The function can return earlier if a signal has been delivered to the -process. -In this case, it returns \-1, sets \fIerrno\fP to +suspends the execution of the calling thread +until either at least the time specified in +.IR *req +has elapsed, or the delivery of a signal +that triggers the invocation of a handler in the calling thread or +that terminates the process. + +If the call is interrupted by a signal handler, +.BR nanosleep () +returns \-1, sets \fIerrno\fP to .BR EINTR , -and writes the -remaining time into the structure pointed to by +and writes the remaining time into the structure pointed to by .I rem unless .I rem @@ -58,15 +69,12 @@ The value of .I *rem can then be used to call .BR nanosleep () -again and complete the specified pause. +again and complete the specified pause (but see NOTES). The structure .I timespec is used to specify intervals of time with nanosecond precision. -It is -specified in -.I -and has the form +It is defined as follows: .sp .in +4n .nf @@ -84,9 +92,12 @@ Compared to and .BR usleep (3), .BR nanosleep () -has the advantage of not affecting any signals, it is standardized by -POSIX, it provides higher timing resolution, and it allows to continue -a sleep that has been interrupted by a signal more easily. +has the the following advantages: +it provides a higher resolution for specifying the sleep interval; +POSIX.1 explicitly specifies that it +does not interact with signals; +and it makes the task of resuming a sleep that has been +interrupted by a signal handler easier. .SH "RETURN VALUE" On successfully sleeping for the requested interval, .BR nanosleep () @@ -102,9 +113,9 @@ Problem with copying information from user space. .TP .B EINTR The pause has been interrupted by a non-blocked signal that was -delivered to the process. +delivered to the thread. The remaining sleep time has been written -into \fI*rem\fP so that the process can easily call +into \fI*rem\fP so that the thread can easily call .BR nanosleep () again and continue with the pause. .TP @@ -117,25 +128,12 @@ was negative. .SH "CONFORMING TO" POSIX.1-2001. .SH BUGS -The current implementation of -.BR nanosleep () -is based on the normal kernel timer mechanism, which has a resolution -of 1/\fIHZ\fP\ s (see -.BR time (7)). -Therefore, -.BR nanosleep () -pauses always for at least the specified time, however it can take up -to 10 ms longer than specified until the process becomes runnable -again. -For the same reason, the value returned in case of a delivered -signal in \fI*rem\fP is usually rounded to the next larger multiple of -1/\fIHZ\fP\ s. .SS "Old behavior" In order to support applications requiring much more precise pauses (e.g., in order to control some time-critical hardware), .BR nanosleep () would handle pauses of up to 2\ ms by busy waiting with microsecond -precision when called from a process scheduled under a real-time policy +precision when called from a thread scheduled under a real-time policy like .B SCHED_FIFO or @@ -150,13 +148,64 @@ is stopped by a signal (e.g., .BR SIGTSTP ), then the call fails with the error .B EINTR -after the process is resumed by a +after the thread is resumed by a .B SIGCONT signal. If the system call is subsequently restarted, -then the time that the process spent in the stopped state is +then the time that the thread spent in the stopped state is \fInot\fP counted against the sleep interval. +.SH NOTES +If the interval specified in +.I req +is not an exact multiple of the granularity underlying clock (see +.BR time (7)), +then the interval will be rounded up to the next multiple. +Furthermore, after the sleep completes, there may still be a delay before +the CPU becomes free to once again execute the calling thread. + +The fact that +.BR nanosleep () +sleeps for a relative interval can be problematic if the call +is repeatedly restarted after being interrupted by signals, +since the time between the interruptions and restarts of the call +will lead to drift in the time when the sleep finally completes. +This problem can be avoided by using +.BR clock_nanosleep (2) +with an absolute time value. + +POSIX.1 specifies that +.BR nanosleep () +should measure time against the +.B CLOCK_REALTIME +clock. +However, Linux measures the time using the +.B CLOCK_MONOTONIC +clock. +.\" See also http://thread.gmane.org/gmane.linux.kernel/696854/ +.\" Subject: nanosleep() uses CLOCK_MONOTONIC, should be CLOCK_REALTIME? +.\" Date: 2008-06-22 07:35:41 GMT +This probably does not matter, since the POSIX.1 specification for +.BR clock_settime () +says that discontinuous changes in +.B CLOCK_REALTIME +should not affect +.BR nanosleep (): +.RS +.PP +Setting the value of the +.B CLOCK_REALTIME +clock via +.BR clock_settime () +shall +have no effect on threads that are blocked waiting for a relative time +service based upon this clock, including the +.BR nanosleep () +function; ... +Consequently, these time services shall expire when the requested relative +interval elapses, independently of the new or old value of the clock. +.RE .SH "SEE ALSO" +.BR clock_nanosleep (2), .BR sched_setscheduler (2), .BR sleep (3), .BR timer_create (3),