[ovs-dev] [PATCH v3] timeval: Use monotonic time in OVS Python timeval library.

YAMAMOTO Takashi yamamoto at valinux.co.jp
Sun Jun 1 06:14:24 UTC 2014


> Python's time.time() function uses the system wall clock. However,
> if NTP resets the wall clock to be a time in the past, then this
> causes any applications that poll block based on time, such as
> ovs-xapi-sync, to poll block indefinitely since the time is
> unexpectedly negative.
> 
> This patch fixes the issue by using time.monotonic() if Python's
> version >= 3.3. Otherwise, the timeval module calls out to the
> librt C shared library and uses the clock_gettime function with
> CLOCK_MONOTONIC.
> 
> Note this is only enabled on Linux-based platforms. This has been
> tested on Ubuntu 12.04 and Redhat 6.4.
> 
> Bug #1189434
> Signed-off-by: Ryan Wilson <wryan at nicira.com>
> 
> ---
> v2: Pre-load librt.so.1 library instead of loading at every function
> call. Use only CLOCK_MONOTONIC for consistency with OVS C library.
> v3: Edit commit message, remove if-linux check
> ---
>  python/ovs/timeval.py |   34 +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/python/ovs/timeval.py b/python/ovs/timeval.py
> index ba0e54e..f2681ac 100644
> --- a/python/ovs/timeval.py
> +++ b/python/ovs/timeval.py
> @@ -12,13 +12,45 @@
>  # See the License for the specific language governing permissions and
>  # limitations under the License.
>  
> +import ctypes
> +import sys
>  import time
>  
> +LIBRT = 'librt.so.1'
> +CLOCK_MONOTONIC = 1
> +
> +class timespec(ctypes.Structure):
> +    _fields_ = [
> +        ('tv_sec', ctypes.c_long),

on NetBSD, timespec.tv_sec is int64_t, not long.

YAMAMOTO Takashi

> +        ('tv_nsec', ctypes.c_long),
> +    ]
> +
> +try:
> +    librt = ctypes.CDLL(LIBRT)
> +    clock_gettime = librt.clock_gettime
> +    clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]
> +except:
> +    # Librt shared library could not be loaded
> +    librt = None
> +
> +def monotonic():
> +    if not librt:
> +        return time.time()
> +
> +    t = timespec()
> +    if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) == 0:
> +        return t.tv_sec + t.tv_nsec * 1e-9
> +    # Kernel does not support CLOCK_MONOTONIC
> +    return time.time()
> +
> +# Use time.monotonic() if Python version >= 3.3
> +if not hasattr(time, 'monotonic'):
> +    time.monotonic = monotonic
>  
>  def msec():
>      """Returns the current time, as the amount of time since the epoch, in
>      milliseconds, as a float."""
> -    return time.time() * 1000.0
> +    return time.monotonic() * 1000.0
>  
>  
>  def postfork():
> -- 
> 1.7.9.5



More information about the dev mailing list