runtime/dyninst/timer.c - systemtap
Data types defined
Functions defined
Macros defined
Source code
/* -*- 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 _STAPDYN_TIMER_C_
#define _STAPDYN_TIMER_C_
#include <signal.h>
#include <time.h>
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC 1000000000L
#endif
struct stap_hrtimer_probe {
struct sigevent sigev;
timer_t timer_id;
struct itimerspec its;
const struct stap_probe * const probe;
int64_t intrv;
int64_t rnd;
};
static void _stp_hrtimer_init(void)
{
return;
}
static int
_stp_hrtimer_start(struct stap_hrtimer_probe *shp)
{
/* Specify a timer with the correct initial value (possibly
* randomized a bit).
*
* If this isn't a randomized timer probe, go ahead and set
* up the repeating interval values.
*
* The probe's interval is in nanoseconds,
* but in a int64_t. So, break it down into seconds and
* (leftover) nanoseconds so it will fit in a 'struct
* timespec'.
*/
if (shp->rnd == 0) {
shp->its.it_value.tv_sec = (shp->its.it_interval.tv_sec \
= shp->intrv / NSEC_PER_SEC);
shp->its.it_value.tv_nsec = (shp->its.it_interval.tv_nsec \
= shp->intrv % NSEC_PER_SEC);
}
else {
int64_t i = shp->intrv + _stp_random_u(shp->rnd);
shp->its.it_value.tv_sec = i / NSEC_PER_SEC;
shp->its.it_value.tv_nsec = i % NSEC_PER_SEC;
}
return timer_settime(shp->timer_id, 0, &shp->its, NULL);
}
static int
_stp_hrtimer_create(struct stap_hrtimer_probe *shp, void (*function)(sigval_t))
{
int rc;
/* Create the timer. */
shp->sigev.sigev_notify = SIGEV_THREAD;
shp->sigev.sigev_value.sival_ptr = shp;
shp->sigev.sigev_notify_function = function;
shp->sigev.sigev_notify_attributes = NULL;
return timer_create(CLOCK_MONOTONIC, &shp->sigev, &shp->timer_id);
}
static void _stp_hrtimer_update(struct stap_hrtimer_probe *shp)
{
int64_t i = shp->intrv;
/* The timer only needs updating if this is a randomized timer
* probe */
if (shp->rnd == 0)
return;
/* The probe's interval is in nanoseconds, but in a
* int64_t. So, break it down into seconds and (leftover)
* nanoseconds.
*/
i += _stp_random_u(shp->rnd);
shp->its.it_value.tv_sec = i / NSEC_PER_SEC;
shp->its.it_value.tv_nsec = i % NSEC_PER_SEC;
timer_settime(shp->timer_id, 0, &shp->its, NULL);
}
static void _stp_hrtimer_cancel(struct stap_hrtimer_probe *shp)
{
shp->its.it_value.tv_sec = 0;
shp->its.it_value.tv_nsec = 0;
timer_settime(shp->timer_id, 0, &shp->its, NULL);
}
static void _stp_hrtimer_delete(struct stap_hrtimer_probe *shp)
{
(void) timer_delete(shp->timer_id);
}
#endif /* _STAPDYN_TIMER_C_ */