update test fair rwlock
[lttv.git] / trunk / tests / kernel / test-fair-rwlock.c
1 /* test-fair-rwlock.c
2 *
3 */
4
5 #include <linux/module.h>
6 #include <linux/proc_fs.h>
7 #include <linux/sched.h>
8 #include <linux/timex.h>
9 #include <linux/fair-rwlock.h>
10 #include <linux/kthread.h>
11 #include <linux/delay.h>
12 #include <linux/hardirq.h>
13 #include <linux/module.h>
14 #include <asm/ptrace.h>
15
16 #if (NR_CPUS > 512 && (BITS_PER_LONG == 32 || NR_CPUS > 1048576))
17 #error "fair rwlock needs more bits per long to deal with that many CPUs"
18 #endif
19
20 #define THREAD_ROFFSET 1UL
21 #define THREAD_RMASK ((NR_CPUS - 1) * THREAD_ROFFSET)
22 #define SOFTIRQ_ROFFSET (THREAD_RMASK + 1)
23 #define SOFTIRQ_RMASK ((NR_CPUS - 1) * SOFTIRQ_ROFFSET)
24 #define HARDIRQ_ROFFSET ((SOFTIRQ_RMASK | THREAD_RMASK) + 1)
25 #define HARDIRQ_RMASK ((NR_CPUS - 1) * HARDIRQ_ROFFSET)
26
27 #define THREAD_WMASK (1UL << (BITS_PER_LONG - 3))
28 #define SOFTIRQ_WMASK (1UL << (BITS_PER_LONG - 2))
29 #define HARDIRQ_WMASK (1UL << (BITS_PER_LONG - 1))
30
31
32 #define NR_VARS 100
33 #define NR_WRITERS 3
34 #define NR_READERS 6
35 #define NR_INTERRUPT_READERS 2
36
37 static int var[NR_VARS];
38 static struct task_struct *reader_threads[NR_READERS];
39 static struct task_struct *writer_threads[NR_WRITERS];
40 static struct task_struct *interrupt_reader;
41
42 static struct fair_rwlock frwlock = {
43 .value = ATOMIC_LONG_INIT(0),
44 .wlock = __SPIN_LOCK_UNLOCKED(&frwlock.wlock),
45 };
46
47 struct proc_dir_entry *pentry = NULL;
48
49 static int reader_thread(void *data)
50 {
51 int i;
52 int prev, cur;
53 unsigned long iter = 0;
54
55 printk("reader_thread/%lu runnning\n", (unsigned long)data);
56 do {
57 iter++;
58 fair_read_lock(&frwlock);
59 prev = var[0];
60 for (i = 1; i < NR_VARS; i++) {
61 cur = var[i];
62 if (cur != prev)
63 printk(KERN_ALERT
64 "Unequal cur %d/prev %d at i %d, iter %lu "
65 "in thread\n", cur, prev, i, iter);
66 }
67 fair_read_unlock(&frwlock);
68 //msleep(100);
69 } while (!kthread_should_stop());
70 printk("reader_thread/%lu iterations : %lu\n",
71 (unsigned long)data, iter);
72 return 0;
73 }
74
75 static void interrupt_reader_ipi(void *data)
76 {
77 int i;
78 int prev, cur;
79
80 fair_read_lock(&frwlock);
81 prev = var[0];
82 for (i = 1; i < NR_VARS; i++) {
83 cur = var[i];
84 if (cur != prev)
85 printk(KERN_ALERT
86 "Unequal cur %d/prev %d at i %d in interrupt\n",
87 cur, prev, i);
88 }
89 fair_read_unlock(&frwlock);
90 }
91
92 static int interrupt_reader_thread(void *data)
93 {
94 unsigned long iter = 0;
95 do {
96 iter++;
97 on_each_cpu(interrupt_reader_ipi, NULL, 0);
98 msleep(100);
99 } while (!kthread_should_stop());
100 printk("interrupt_reader_thread/%lu iterations : %lu\n",
101 (unsigned long)data, iter);
102 return 0;
103 }
104
105 static int writer_thread(void *data)
106 {
107 int i;
108 int new;
109 unsigned long iter = 0;
110
111 printk("writer_thread/%lu runnning\n", (unsigned long)data);
112 do {
113 iter++;
114 fair_write_lock_irq(&frwlock);
115 //fair_write_lock(&frwlock);
116 new = (int)get_cycles();
117 for (i = 0; i < NR_VARS; i++) {
118 var[i] = new;
119 }
120 //fair_write_unlock(&frwlock);
121 fair_write_unlock_irq(&frwlock);
122 //msleep(100);
123 } while (!kthread_should_stop());
124 printk("writer_thread/%lu iterations : %lu\n",
125 (unsigned long)data, iter);
126 return 0;
127 }
128
129 static void fair_rwlock_create(void)
130 {
131 unsigned long i;
132
133 for (i = 0; i < NR_READERS; i++) {
134 printk("starting reader thread %lu\n", i);
135 reader_threads[i] = kthread_run(reader_thread, (void *)i,
136 "frwlock_reader");
137 BUG_ON(!reader_threads[i]);
138 }
139
140 printk("starting interrupt reader %lu\n", i);
141 interrupt_reader = kthread_run(interrupt_reader_thread, NULL,
142 "frwlock_interrupt_reader");
143
144 for (i = 0; i < NR_WRITERS; i++) {
145 printk("starting writer thread %lu\n", i);
146 writer_threads[i] = kthread_run(writer_thread, (void *)i,
147 "frwlock_writer");
148 BUG_ON(!writer_threads[i]);
149 }
150 }
151
152 static void fair_rwlock_stop(void)
153 {
154 unsigned long i;
155
156 for (i = 0; i < NR_READERS; i++) {
157 kthread_stop(reader_threads[i]);
158 }
159
160 //kthread_stop(interrupt_reader);
161
162 for (i = 0; i < NR_WRITERS; i++) {
163 kthread_stop(writer_threads[i]);
164 }
165 }
166
167
168 static void perform_test(const char *name, void (*callback)(void))
169 {
170 printk("%s\n", name);
171 callback();
172 }
173
174 static int my_open(struct inode *inode, struct file *file)
175 {
176 perform_test("fair-rwlock-create", fair_rwlock_create);
177 ssleep(30);
178 perform_test("fair-rwlock-stop", fair_rwlock_stop);
179
180 return -EPERM;
181 }
182
183
184 static struct file_operations my_operations = {
185 .open = my_open,
186 };
187
188 int init_module(void)
189 {
190 pentry = create_proc_entry("testfrwlock", 0444, NULL);
191 if (pentry)
192 pentry->proc_fops = &my_operations;
193
194 printk("NR_CPUS : %d\n", NR_CPUS);
195 printk("THREAD_ROFFSET : %lX\n", THREAD_ROFFSET);
196 printk("THREAD_RMASK : %lX\n", THREAD_RMASK);
197 printk("THREAD_WMASK : %lX\n", THREAD_WMASK);
198 printk("SOFTIRQ_ROFFSET : %lX\n", SOFTIRQ_ROFFSET);
199 printk("SOFTIRQ_RMASK : %lX\n", SOFTIRQ_RMASK);
200 printk("SOFTIRQ_WMASK : %lX\n", SOFTIRQ_WMASK);
201 printk("HARDIRQ_ROFFSET : %lX\n", HARDIRQ_ROFFSET);
202 printk("HARDIRQ_RMASK : %lX\n", HARDIRQ_RMASK);
203 printk("HARDIRQ_WMASK : %lX\n", HARDIRQ_WMASK);
204
205 return 0;
206 }
207
208 void cleanup_module(void)
209 {
210 remove_proc_entry("testfrwlock", NULL);
211 }
212
213 MODULE_LICENSE("GPL");
214 MODULE_AUTHOR("Mathieu Desnoyers");
215 MODULE_DESCRIPTION("Fair rwlock test");
This page took 0.054349 seconds and 4 git commands to generate.