aboutsummaryrefslogtreecommitdiff
path: root/driver/gator_hrtimer_gator.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/gator_hrtimer_gator.c')
-rw-r--r--driver/gator_hrtimer_gator.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/driver/gator_hrtimer_gator.c b/driver/gator_hrtimer_gator.c
index 5896b3c..846fba4 100644
--- a/driver/gator_hrtimer_gator.c
+++ b/driver/gator_hrtimer_gator.c
@@ -13,6 +13,7 @@
void (*callback)(void);
DEFINE_PER_CPU(struct hrtimer, percpu_hrtimer);
+DEFINE_PER_CPU(int, hrtimer_is_active);
static ktime_t profiling_interval;
static void gator_hrtimer_online(int cpu);
static void gator_hrtimer_offline(int cpu);
@@ -32,11 +33,16 @@ static void gator_hrtimer_switch_cpus_online(void *unused)
static void gator_hrtimer_online(int cpu)
{
struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu);
+
if (cpu != smp_processor_id()) {
smp_call_function_single(cpu, gator_hrtimer_switch_cpus_online, NULL, 1);
return;
}
+ if (per_cpu(hrtimer_is_active, cpu) || profiling_interval.tv64 == 0)
+ return;
+
+ per_cpu(hrtimer_is_active, cpu) = 1;
hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer->function = gator_hrtimer_notify;
hrtimer_start(hrtimer, profiling_interval, HRTIMER_MODE_REL_PINNED);
@@ -50,20 +56,35 @@ static void gator_hrtimer_switch_cpus_offline(void *unused)
static void gator_hrtimer_offline(int cpu)
{
struct hrtimer *hrtimer = &per_cpu(percpu_hrtimer, cpu);
+
if (cpu != smp_processor_id()) {
smp_call_function_single(cpu, gator_hrtimer_switch_cpus_offline, NULL, 1);
return;
}
+ if (!per_cpu(hrtimer_is_active, cpu))
+ return;
+
+ per_cpu(hrtimer_is_active, cpu) = 0;
hrtimer_cancel(hrtimer);
}
static int gator_hrtimer_init(int interval, void (*func)(void))
{
+ int cpu;
+
(callback) = (func);
+ for_each_present_cpu(cpu) {
+ per_cpu(hrtimer_is_active, cpu) = 0;
+ }
+
// calculate profiling interval
- profiling_interval = ns_to_ktime(1000000000UL / interval);
+ if (interval > 0) {
+ profiling_interval = ns_to_ktime(1000000000UL / interval);
+ } else {
+ profiling_interval.tv64 = 0;
+ }
return 0;
}