From 6b5c6447ae8d0eed1065ef56bc483eed737e3b9e Mon Sep 17 00:00:00 2001 From: jistone Date: Fri, 7 Apr 2006 18:52:36 +0000 Subject: [PATCH] 2006-04-07 Josh Stone PR2525 * timestamp.stp (__check_xtime_lock): check if xtime is available (gettimeofday_s, gettimeofday_ms, gettimeofday_us): error out if called when xtime is not available, to avoid deadlock --- tapset/ChangeLog | 7 +++++ tapset/timestamp.stp | 63 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/tapset/ChangeLog b/tapset/ChangeLog index bdad3877d..90e6af3e8 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,10 @@ +2006-04-07 Josh Stone + + PR2525 + * timestamp.stp (__check_xtime_lock): check if xtime is available + (gettimeofday_s, gettimeofday_ms, gettimeofday_us): error out if + called when xtime is not available, to avoid deadlock + 2006-03-06 Martin Hunt * system.stp: New tapset. diff --git a/tapset/timestamp.stp b/tapset/timestamp.stp index ee9478cbc..43fb4703b 100644 --- a/tapset/timestamp.stp +++ b/tapset/timestamp.stp @@ -1,5 +1,6 @@ // timestamp tapset // Copyright (C) 2005-2006 Red Hat Inc. +// Copyright (C) 2006 Intel Corporation. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -9,6 +10,23 @@ %{ #include + +/* Try to determine the status of xtime_lock. + * Returns: zero if xtime_lock was found valid for reading + * non-zero if we waited too long for availability + */ +static inline int __check_xtime_lock(void) +{ + unsigned numtrylock = 0; + unsigned seq = read_seqbegin(&xtime_lock); + while (read_seqretry(&xtime_lock, seq)) { + if (++numtrylock >= MAXTRYLOCK) + return 1; + ndelay(TRYLOCKDELAY); + seq = read_seqbegin(&xtime_lock); + } + return 0; +} %} @@ -21,23 +39,50 @@ function get_cycles:long () %{ // return in microseconds since epoch function gettimeofday_us:long () %{ - struct timeval tm; - do_gettimeofday (& tm); - THIS->__retvalue = (tm.tv_sec * 1000000ULL) + (tm.tv_usec); + if (__check_xtime_lock()) + { + /* TODO: is there a way to approximate gettimeofday? */ + CONTEXT->last_error = "unable to call do_gettimeofday"; + THIS->__retvalue = 0LL; + } + else + { + struct timeval tm; + do_gettimeofday (& tm); + THIS->__retvalue = (tm.tv_sec * 1000000ULL) + (tm.tv_usec); + } %} // return in milliseconds since epoch function gettimeofday_ms:long () %{ - struct timeval tm; - do_gettimeofday (& tm); - THIS->__retvalue = (tm.tv_sec * 1000ULL) + (tm.tv_usec / 1000); + if (__check_xtime_lock()) + { + /* TODO: is there a way to approximate gettimeofday? */ + CONTEXT->last_error = "unable to call do_gettimeofday"; + THIS->__retvalue = 0LL; + } + else + { + struct timeval tm; + do_gettimeofday (& tm); + THIS->__retvalue = (tm.tv_sec * 1000ULL) + (tm.tv_usec / 1000); + } %} // return in seconds since epoch function gettimeofday_s:long () %{ - struct timeval tm; - do_gettimeofday (& tm); - THIS->__retvalue = tm.tv_sec; + if (__check_xtime_lock()) + { + /* TODO: is there a way to approximate gettimeofday? */ + CONTEXT->last_error = "unable to call do_gettimeofday"; + THIS->__retvalue = 0LL; + } + else + { + struct timeval tm; + do_gettimeofday (& tm); + THIS->__retvalue = tm.tv_sec; + } %} // likewise jiffies, monotonic_clock ... -- 2.43.5