diff options
Diffstat (limited to 'driver/gator_hrtimer_gator.c')
-rw-r--r-- | driver/gator_hrtimer_gator.c | 23 |
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; } |