/usr/share/systemtap/runtime/linux/timer.c is in systemtap-common 2.3-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | /* -*- linux-c -*-
* Dyninst Timer Functions
* Copyright (C) 2012 Red Hat Inc.
*
* 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
* Public License (GPL); either version 2, or (at your option) any
* later version.
*/
#ifndef _LINUX_TIMER_C_
#define _LINUX_TIMER_C_
// If we're on kernels >= 2.6.17, use hrtimers.
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
static unsigned long stap_hrtimer_resolution = 0;
struct stap_hrtimer_probe {
struct hrtimer hrtimer;
const struct stap_probe * const probe;
int64_t intrv;
int64_t rnd;
};
// The function signature changed in 2.6.21.
#ifdef STAPCONF_HRTIMER_REL
typedef int hrtimer_return_t;
#else
typedef enum hrtimer_restart hrtimer_return_t;
#endif
// autoconf: add get/set expires if missing (pre 2.6.28-rc1)
#ifndef STAPCONF_HRTIMER_GETSET_EXPIRES
#define hrtimer_get_expires(timer) ((timer)->expires)
#define hrtimer_set_expires(timer, time) (void)((timer)->expires = (time))
#endif
// autoconf: adapt to HRTIMER_REL -> HRTIMER_MODE_REL renaming near 2.6.21
#ifdef STAPCONF_HRTIMER_REL
#define HRTIMER_MODE_REL HRTIMER_REL
#endif
static void _stp_hrtimer_init(void)
{
struct timespec res;
hrtimer_get_res (CLOCK_MONOTONIC, &res);
stap_hrtimer_resolution = timespec_to_ns(&res);
}
static inline ktime_t _stp_hrtimer_get_interval(struct stap_hrtimer_probe *stp)
{
unsigned long nsecs;
uint64_t i = stp->intrv;
if (stp->rnd != 0) {
#if 1
// XXX: why not use stp_random_pm instead of this?
int64_t r;
get_random_bytes(&r, sizeof(r));
// ensure that r is positive
r &= ((uint64_t)1 << (8*sizeof(r) - 1)) - 1;
r = _stp_mod64(NULL, r, (2*stp->rnd+1));
r -= stp->rnd;
i += r;
#else
i += _stp_random_pm(stp->rnd);
#endif
}
if (unlikely(i < stap_hrtimer_resolution))
i = stap_hrtimer_resolution;
nsecs = do_div(i, NSEC_PER_SEC);
return ktime_set(i, nsecs);
}
static inline void _stp_hrtimer_update(struct stap_hrtimer_probe *stp)
{
ktime_t time;
time = ktime_add(hrtimer_get_expires(&stp->hrtimer),
_stp_hrtimer_get_interval(stp));
hrtimer_set_expires(&stp->hrtimer, time);
}
static int
_stp_hrtimer_create(struct stap_hrtimer_probe *stp,
hrtimer_return_t (*function)(struct hrtimer *))
{
hrtimer_init(&stp->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
stp->hrtimer.function = function;
(void)hrtimer_start(&stp->hrtimer, _stp_hrtimer_get_interval(stp),
HRTIMER_MODE_REL);
return 0;
}
static void
_stp_hrtimer_cancel(struct stap_hrtimer_probe *stp)
{
hrtimer_cancel(&stp->hrtimer);
}
#else /* kernel version < 2.6.17 */
#error "not implemented"
#endif /* kernel version < 2.6.17 */
#endif /* _LINUX_TIMER_C_ */
|