+
+/*
+ * appldata_mod_vtimer_wrap()
+ *
+ * wrapper function for mod_virt_timer(), because smp_call_function_on()
+ * accepts only one parameter.
+ */
+static void __appldata_mod_vtimer_wrap(void *p) {
+ struct {
+ struct vtimer_list *timer;
+ u64 expires;
+ } *args = p;
+ mod_virt_timer(args->timer, args->expires);
+}
+
+#define APPLDATA_ADD_TIMER 0
+#define APPLDATA_DEL_TIMER 1
+#define APPLDATA_MOD_TIMER 2
+
+/*
+ * __appldata_vtimer_setup()
+ *
+ * Add, delete or modify virtual timers on all online cpus.
+ * The caller needs to get the appldata_timer_lock spinlock.
+ */
+static void
+__appldata_vtimer_setup(int cmd)
+{
+ u64 per_cpu_interval;
+ int i;
+
+ switch (cmd) {
+ case APPLDATA_ADD_TIMER:
+ if (appldata_timer_active)
+ break;
+ per_cpu_interval = (u64) (appldata_interval*1000 /
+ num_online_cpus()) * TOD_MICRO;
+ for_each_online_cpu(i) {
+ per_cpu(appldata_timer, i).expires = per_cpu_interval;
+ smp_call_function_on(add_virt_timer_periodic,
+ &per_cpu(appldata_timer, i),
+ 0, 1, i);
+ }
+ appldata_timer_active = 1;
+ P_INFO("Monitoring timer started.\n");
+ break;
+ case APPLDATA_DEL_TIMER:
+ for_each_online_cpu(i)
+ del_virt_timer(&per_cpu(appldata_timer, i));
+ if (!appldata_timer_active)
+ break;
+ appldata_timer_active = 0;
+ atomic_set(&appldata_expire_count, num_online_cpus());
+ P_INFO("Monitoring timer stopped.\n");
+ break;
+ case APPLDATA_MOD_TIMER:
+ per_cpu_interval = (u64) (appldata_interval*1000 /
+ num_online_cpus()) * TOD_MICRO;
+ if (!appldata_timer_active)
+ break;
+ for_each_online_cpu(i) {
+ struct {
+ struct vtimer_list *timer;
+ u64 expires;
+ } args;
+ args.timer = &per_cpu(appldata_timer, i);
+ args.expires = per_cpu_interval;
+ smp_call_function_on(__appldata_mod_vtimer_wrap,
+ &args, 0, 1, i);
+ }
+ }
+}
+