update
[lttv.git] / tests / kernel / test-cmpxchg-nolock2.c
1 /* test-cmpxchg-nolock.c
2 *
3 * Compare local cmpxchg with irq disable / enable.
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/calc64.h>
12 #include <asm/timex.h>
13 #include <asm/system.h>
14
15 #define NR_LOOPS 20000
16
17 int test_val;
18
19 static void do_testbaseline(void)
20 {
21 int ret;
22 long flags;
23 unsigned int i;
24 cycles_t time1, time2, time;
25 long rem;
26
27 local_irq_save(flags);
28 preempt_disable();
29 time1 = get_cycles();
30 for (i = 0; i < NR_LOOPS; i++) {
31 asm volatile ("");
32 }
33 time2 = get_cycles();
34 local_irq_restore(flags);
35 preempt_enable();
36 time = time2 - time1;
37
38 printk(KERN_ALERT "test results: time for baseline\n");
39 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
40 printk(KERN_ALERT "total time: %llu\n", time);
41 time = div_long_long_rem(time, NR_LOOPS, &rem);
42 printk(KERN_ALERT "-> baseline takes %llu cycles\n", time);
43 printk(KERN_ALERT "test end\n");
44 }
45
46 static void do_test_sync_cmpxchg(void)
47 {
48 int ret;
49 long flags;
50 unsigned int i;
51 cycles_t time1, time2, time;
52 long rem;
53
54 local_irq_save(flags);
55 preempt_disable();
56 time1 = get_cycles();
57 for (i = 0; i < NR_LOOPS; i++) {
58 #ifdef CONFIG_X86_32
59 ret = sync_cmpxchg(&test_val, 0, 0);
60 #else
61 ret = cmpxchg(&test_val, 0, 0);
62 #endif
63 }
64 time2 = get_cycles();
65 local_irq_restore(flags);
66 preempt_enable();
67 time = time2 - time1;
68
69 printk(KERN_ALERT "test results: time for locked cmpxchg\n");
70 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
71 printk(KERN_ALERT "total time: %llu\n", time);
72 time = div_long_long_rem(time, NR_LOOPS, &rem);
73 printk(KERN_ALERT "-> locked cmpxchg takes %llu cycles\n", time);
74 printk(KERN_ALERT "test end\n");
75 }
76
77 static void do_test_cmpxchg(void)
78 {
79 int ret;
80 long flags;
81 unsigned int i;
82 cycles_t time1, time2, time;
83 long rem;
84
85 local_irq_save(flags);
86 preempt_disable();
87 time1 = get_cycles();
88 for (i = 0; i < NR_LOOPS; i++) {
89 ret = cmpxchg_local(&test_val, 0, 0);
90 }
91 time2 = get_cycles();
92 local_irq_restore(flags);
93 preempt_enable();
94 time = time2 - time1;
95
96 printk(KERN_ALERT "test results: time for non locked cmpxchg\n");
97 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
98 printk(KERN_ALERT "total time: %llu\n", time);
99 time = div_long_long_rem(time, NR_LOOPS, &rem);
100 printk(KERN_ALERT "-> non locked cmpxchg takes %llu cycles\n", time);
101 printk(KERN_ALERT "test end\n");
102 }
103
104 /*
105 * This test will have a higher standard deviation due to incoming interrupts.
106 */
107 static void do_test_enable_int(void)
108 {
109 long flags;
110 unsigned int i;
111 cycles_t time1, time2, time;
112 long rem;
113
114 local_irq_save(flags);
115 preempt_disable();
116 time1 = get_cycles();
117 for (i = 0; i < NR_LOOPS; i++) {
118 local_irq_restore(flags);
119 }
120 time2 = get_cycles();
121 local_irq_restore(flags);
122 preempt_enable();
123 time = time2 - time1;
124
125 printk(KERN_ALERT "test results: time for enabling interrupts (STI)\n");
126 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
127 printk(KERN_ALERT "total time: %llu\n", time);
128 time = div_long_long_rem(time, NR_LOOPS, &rem);
129 printk(KERN_ALERT "-> enabling interrupts (STI) takes %llu cycles\n",
130 time);
131 printk(KERN_ALERT "test end\n");
132 }
133
134 static void do_test_disable_int(void)
135 {
136 unsigned long flags, flags2;
137 unsigned int i;
138 cycles_t time1, time2, time;
139 long rem;
140
141 local_irq_save(flags);
142 preempt_disable();
143 time1 = get_cycles();
144 for ( i = 0; i < NR_LOOPS; i++) {
145 local_irq_save(flags2);
146 }
147 time2 = get_cycles();
148 local_irq_restore(flags);
149 preempt_enable();
150 time = time2 - time1;
151
152 printk(KERN_ALERT "test results: time for disabling interrupts (CLI)\n");
153 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
154 printk(KERN_ALERT "total time: %llu\n", time);
155 time = div_long_long_rem(time, NR_LOOPS, &rem);
156 printk(KERN_ALERT "-> disabling interrupts (CLI) takes %llu cycles\n",
157 time);
158 printk(KERN_ALERT "test end\n");
159 }
160
161 static void do_test_int(void)
162 {
163 long flags;
164 unsigned int i;
165 cycles_t time1, time2, time;
166 long rem;
167
168 local_irq_save(flags);
169 preempt_disable();
170 time1 = get_cycles();
171 for (i = 0; i < NR_LOOPS; i++) {
172 local_irq_restore(flags);
173 local_irq_save(flags);
174 }
175 time2 = get_cycles();
176 local_irq_restore(flags);
177 preempt_enable();
178 time = time2 - time1;
179
180 printk(KERN_ALERT "test results: time for disabling/enabling interrupts (STI/CLI)\n");
181 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
182 printk(KERN_ALERT "total time: %llu\n", time);
183 time = div_long_long_rem(time, NR_LOOPS, &rem);
184 printk(KERN_ALERT "-> enabling/disabling interrupts (STI/CLI) takes %llu cycles\n",
185 time);
186 printk(KERN_ALERT "test end\n");
187 }
188
189
190
191 static int ltt_test_init(void)
192 {
193 printk(KERN_ALERT "test init\n");
194
195 do_testbaseline();
196 do_test_sync_cmpxchg();
197 do_test_cmpxchg();
198 do_test_enable_int();
199 do_test_disable_int();
200 do_test_int();
201 return -EAGAIN; /* Fail will directly unload the module */
202 }
203
204 static void ltt_test_exit(void)
205 {
206 printk(KERN_ALERT "test exit\n");
207 }
208
209 module_init(ltt_test_init)
210 module_exit(ltt_test_exit)
211
212 MODULE_LICENSE("GPL");
213 MODULE_AUTHOR("Mathieu Desnoyers");
214 MODULE_DESCRIPTION("Cmpxchg vs int Test");
215
This page took 0.03347 seconds and 4 git commands to generate.