move all projects into the trunk directory
[lttv.git] / trunk / 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 static void do_test_sync_inc(void)
104 {
105 int ret;
106 long flags;
107 unsigned int i;
108 cycles_t time1, time2, time;
109 long rem;
110 atomic_t val;
111
112 local_irq_save(flags);
113 preempt_disable();
114 time1 = get_cycles();
115 for (i = 0; i < NR_LOOPS; i++) {
116 ret = atomic_add_return(10, &val);
117 }
118 time2 = get_cycles();
119 local_irq_restore(flags);
120 preempt_enable();
121 time = time2 - time1;
122
123 printk(KERN_ALERT "test results: time for locked add return\n");
124 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
125 printk(KERN_ALERT "total time: %llu\n", time);
126 time = div_long_long_rem(time, NR_LOOPS, &rem);
127 printk(KERN_ALERT "-> locked add return takes %llu cycles\n", time);
128 printk(KERN_ALERT "test end\n");
129 }
130
131
132 static void do_test_inc(void)
133 {
134 int ret;
135 long flags;
136 unsigned int i;
137 cycles_t time1, time2, time;
138 long rem;
139 local_t loc_val;
140
141 local_irq_save(flags);
142 preempt_disable();
143 time1 = get_cycles();
144 for (i = 0; i < NR_LOOPS; i++) {
145 ret = local_add_return(10, &loc_val);
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 non locked add return\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 "-> non locked add return takes %llu cycles\n", time);
157 printk(KERN_ALERT "test end\n");
158 }
159
160
161
162 /*
163 * This test will have a higher standard deviation due to incoming interrupts.
164 */
165 static void do_test_enable_int(void)
166 {
167 long flags;
168 unsigned int i;
169 cycles_t time1, time2, time;
170 long rem;
171
172 local_irq_save(flags);
173 preempt_disable();
174 time1 = get_cycles();
175 for (i = 0; i < NR_LOOPS; i++) {
176 local_irq_restore(flags);
177 }
178 time2 = get_cycles();
179 local_irq_restore(flags);
180 preempt_enable();
181 time = time2 - time1;
182
183 printk(KERN_ALERT "test results: time for enabling interrupts (STI)\n");
184 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
185 printk(KERN_ALERT "total time: %llu\n", time);
186 time = div_long_long_rem(time, NR_LOOPS, &rem);
187 printk(KERN_ALERT "-> enabling interrupts (STI) takes %llu cycles\n",
188 time);
189 printk(KERN_ALERT "test end\n");
190 }
191
192 static void do_test_disable_int(void)
193 {
194 unsigned long flags, flags2;
195 unsigned int i;
196 cycles_t time1, time2, time;
197 long rem;
198
199 local_irq_save(flags);
200 preempt_disable();
201 time1 = get_cycles();
202 for ( i = 0; i < NR_LOOPS; i++) {
203 local_irq_save(flags2);
204 }
205 time2 = get_cycles();
206 local_irq_restore(flags);
207 preempt_enable();
208 time = time2 - time1;
209
210 printk(KERN_ALERT "test results: time for disabling interrupts (CLI)\n");
211 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
212 printk(KERN_ALERT "total time: %llu\n", time);
213 time = div_long_long_rem(time, NR_LOOPS, &rem);
214 printk(KERN_ALERT "-> disabling interrupts (CLI) takes %llu cycles\n",
215 time);
216 printk(KERN_ALERT "test end\n");
217 }
218
219 static void do_test_int(void)
220 {
221 long flags;
222 unsigned int i;
223 cycles_t time1, time2, time;
224 long rem;
225
226 local_irq_save(flags);
227 preempt_disable();
228 time1 = get_cycles();
229 for (i = 0; i < NR_LOOPS; i++) {
230 local_irq_restore(flags);
231 local_irq_save(flags);
232 }
233 time2 = get_cycles();
234 local_irq_restore(flags);
235 preempt_enable();
236 time = time2 - time1;
237
238 printk(KERN_ALERT "test results: time for disabling/enabling interrupts (STI/CLI)\n");
239 printk(KERN_ALERT "number of loops: %d\n", NR_LOOPS);
240 printk(KERN_ALERT "total time: %llu\n", time);
241 time = div_long_long_rem(time, NR_LOOPS, &rem);
242 printk(KERN_ALERT "-> enabling/disabling interrupts (STI/CLI) takes %llu cycles\n",
243 time);
244 printk(KERN_ALERT "test end\n");
245 }
246
247
248
249 static int ltt_test_init(void)
250 {
251 printk(KERN_ALERT "test init\n");
252
253 do_testbaseline();
254 do_test_sync_cmpxchg();
255 do_test_cmpxchg();
256 do_test_sync_inc();
257 do_test_inc();
258 do_test_enable_int();
259 do_test_disable_int();
260 do_test_int();
261 return -EAGAIN; /* Fail will directly unload the module */
262 }
263
264 static void ltt_test_exit(void)
265 {
266 printk(KERN_ALERT "test exit\n");
267 }
268
269 module_init(ltt_test_init)
270 module_exit(ltt_test_exit)
271
272 MODULE_LICENSE("GPL");
273 MODULE_AUTHOR("Mathieu Desnoyers");
274 MODULE_DESCRIPTION("Cmpxchg vs int Test");
275
This page took 0.039168 seconds and 4 git commands to generate.