summaryrefslogtreecommitdiffstats
path: root/tapset/timestamp.stp
diff options
context:
space:
mode:
authorjistone <jistone>2006-04-07 18:52:36 +0000
committerjistone <jistone>2006-04-07 18:52:36 +0000
commit6b5c6447ae8d0eed1065ef56bc483eed737e3b9e (patch)
treeec3b7eadf4e3d87c7e10e53077292eaeaa52c943 /tapset/timestamp.stp
parentf38806c7db98222274d6ef2466d0966f85a797ac (diff)
downloadsystemtap-steved-6b5c6447ae8d0eed1065ef56bc483eed737e3b9e.tar.gz
systemtap-steved-6b5c6447ae8d0eed1065ef56bc483eed737e3b9e.tar.xz
systemtap-steved-6b5c6447ae8d0eed1065ef56bc483eed737e3b9e.zip
2006-04-07 Josh Stone <joshua.i.stone@intel.com>
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
Diffstat (limited to 'tapset/timestamp.stp')
-rw-r--r--tapset/timestamp.stp63
1 files changed, 54 insertions, 9 deletions
diff --git a/tapset/timestamp.stp b/tapset/timestamp.stp
index ee9478cb..43fb4703 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 <linux/time.h>
+
+/* 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 ...