#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/notifier.h>
#include <linux/kmemprof.h>

MODULE_LICENSE("GPL");

static unsigned int freq[NR_CPUS];
MODULE_PARM(freq, "1-" __MODULE_STRING(NR_CPUS) "i");

static unsigned long event_counter[NR_CPUS];

static int kmemprof_freqctrl (struct notifier_block * self, unsigned long val,
			void * arg)
{
	int ret = NOTIFY_OK;
	unsigned int cpu_id = smp_processor_id();
	unsigned int freqency = freq[cpu_id];

	if (!freqency || !(event_counter[cpu_id]++ % freqency)) {
		ret |= NOTIFY_STOP_MASK;
	}

	return ret;
}

static struct notifier_block freqctrl_nb = {
	.notifier_call = &kmemprof_freqctrl,
	.priority = 90
};

static int __init mymodule_init(void)
{
	int i;

	for (i = 0; i < NR_CPUS; i++) {
		printk("%d,", freq[i]);
	}
	printk("\n");
	kmemprof_notifier_chain_register(&freqctrl_nb);

	return 0;
}

static void __exit mymodule_exit(void)
{
	kmemprof_notifier_chain_unregister(&freqctrl_nb);
}

module_init(mymodule_init);
module_exit(mymodule_exit);

