41a0bd4f |
1 | /* rdtsc-smp |
2 | * |
3 | * Test TSC |
4 | */ |
5 | |
6 | |
7 | #include <linux/jiffies.h> |
8 | #include <linux/compiler.h> |
9 | #include <linux/init.h> |
10 | #include <linux/module.h> |
11 | #include <linux/workqueue.h> |
12 | |
13 | static atomic_t busy_wait; |
14 | static struct delayed_work testwork[NR_CPUS]; |
15 | |
16 | |
17 | static void do_work(struct work_struct *work) |
18 | { |
19 | cycles_t val; |
20 | int cpu1, cpu2; |
21 | int num_online = num_online_cpus(); |
22 | int copybusy; |
23 | int i; |
24 | |
25 | cpu1 = smp_processor_id(); |
26 | printk("Busy waiting on cpu %d\n", cpu1); |
27 | |
28 | /* Prime busy_wait in cache */ |
29 | for(i=0; i<100; i++) { |
30 | copybusy = atomic_read(&busy_wait); |
31 | } |
32 | barrier(); |
33 | atomic_inc(&busy_wait); |
34 | while(atomic_read(&busy_wait) != num_online) { |
35 | barrier(); |
36 | } |
37 | |
38 | val = get_cycles(); |
39 | |
40 | cpu2 = smp_processor_id(); |
41 | BUG_ON(cpu1 != cpu2); |
42 | printk("Cycle count on cpu %d is %llu\n", cpu1, val); |
43 | } |
44 | |
45 | |
46 | static int ltt_test_init(void) |
47 | { |
48 | int cpu; |
49 | |
50 | printk(KERN_ALERT "test init\n"); |
51 | |
52 | atomic_set(&busy_wait, 0); |
53 | for_each_online_cpu(cpu) { |
54 | INIT_DELAYED_WORK(&testwork[cpu], do_work); |
55 | schedule_delayed_work_on(cpu, &testwork[cpu], 0); |
56 | } |
57 | return 0; |
58 | } |
59 | |
60 | static void ltt_test_exit(void) |
61 | { |
62 | /* Test program... wait for output before unload */ |
63 | printk(KERN_ALERT "test exit\n"); |
64 | } |
65 | |
66 | module_init(ltt_test_init) |
67 | module_exit(ltt_test_exit) |
68 | |
69 | MODULE_LICENSE("GPL"); |
70 | MODULE_AUTHOR("Mathieu Desnoyers"); |
71 | MODULE_DESCRIPTION("Linux Trace Toolkit Test"); |
72 | |