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