]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/dde/linux26/examples/dde26_test/main.c
261dda03d2ec1ed09c815f37c28db5e433f63420
[l4.git] / l4 / pkg / dde / linux26 / examples / dde26_test / main.c
1 /*
2  * \brief   DDE for Linux 2.6 test program
3  * \author  Bjoern Doebel <doebel@os.inf.tu-dresden.de>
4  * \author  Christian Helmuth <ch12@os.inf.tu-dresden.de>
5  * \date    2007-01-22
6  */
7
8 #include <asm/current.h>
9
10 #include <linux/kernel.h>
11 #include <linux/completion.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/wait.h>
15 #include <linux/sched.h>
16 #include <linux/workqueue.h>
17 #include <linux/interrupt.h>
18 //#include <linux/kthread.h>
19
20 #include <l4/dde/dde.h>
21 #include <l4/dde/ddekit/initcall.h>
22 #include <l4/dde/linux26/dde26.h>
23
24 #include <l4/util/parse_cmd.h>
25 #include <l4/util/util.h>
26 #include <l4/log/log.h>
27
28 /* We define 4 initcalls and see if these are executed
29  * in the beginning.
30  */
31 static __init void foo(void) { printk("foo  module_init\n"); }
32 static __init void bar(void) { printk("bar  device_initcall\n"); }
33 static __init void bla(void) { printk("bla  arch_initcall\n"); }
34 static __init void blub(void) { printk("blub subsys_initcall\n"); }
35 module_init(foo);
36 device_initcall(bar);
37 arch_initcall(bla);
38 subsys_initcall(blub);
39
40 /***********************************************************************
41  ** Test 1: Check whether the current() macro works.                  **
42  ***********************************************************************/
43 static void current_test(void)
44 {
45         struct task_struct *t = NULL;
46
47         printk("Current() test.\n");
48
49         t = current;
50         printk("\tt = %p\n", t);
51 }
52
53
54 /***********************************************************************
55  ** Test 2: Getting complicated. Test startup of some kernel threads  **
56  **         and wait for them to finish using completions.            **
57  ***********************************************************************/
58 #define NUM_KTHREADS    5
59 static struct completion _kthread_completions_[NUM_KTHREADS];
60
61 static int kernel_thread_func(void *arg)
62 {
63         printk("\t\tKernel thread %d\n", (int)arg);
64         printk("\t\tcurrent = %p\n", current);
65
66         /* do some work */
67         msleep(200);
68
69         complete_and_exit( &_kthread_completions_[(int)arg], 0 );
70         return 0;
71 }
72
73
74 static void kernel_thread_test(void)
75 {
76         int i;
77         printk("Testing kernel_thread()\n");
78         for (i=0; i < NUM_KTHREADS; i++) {
79                 int j;
80                 printk("\tInitializing completion for kernel thread.%x\n", i+1);
81                 init_completion(&_kthread_completions_[i]);
82                 printk("\tStarting kthread.%x\n", i+1);
83                 j = kernel_thread(kernel_thread_func, (void *)i, 0);
84                 printk("\treturn: %d\n", j);
85         }
86
87         for (i=0; i < NUM_KTHREADS; i++) {
88                 printk("\tWaiting for kthread.%x to complete.\n", i+1);
89                 wait_for_completion(&_kthread_completions_[i]);
90                 printk("\tkthread.%x has exited.\n", i+1);
91         }
92 }
93
94
95 /******************************************************************************
96  ** Test 3: Test kernel wait queues: start a thread incrementing wait_value, **
97  **         and  sleep until wait_value is larger than 6 for the first time. **
98  ******************************************************************************/
99 static DECLARE_WAIT_QUEUE_HEAD(_wq_head);
100 static int wait_value = 0;
101 static struct completion wq_completion;
102
103 static int inc_func(void *arg)
104 {
105         int i = 0;
106
107         printk("\033[33mI am counting up wait_value.\033[0m\n");
108         for (i=0; i<10; i++)
109         {
110                 printk("\033[33mwait_value: %d\033[0m\n", ++wait_value);
111                 wake_up(&_wq_head);
112                 msleep(500);
113         }
114         complete_and_exit(&wq_completion, 0);
115 }
116
117
118 static void wq_test(void)
119 {
120         int pid;
121         printk("\033[32mWait_queue test. I'm waiting vor wait_value to become >6.\033[0m\n");
122
123         init_completion(&wq_completion);
124         pid = kernel_thread(inc_func, 0, 0);
125
126         wait_event(_wq_head, wait_value > 6);
127         printk("\033[32;1mwait_value > 6 occured!\033[0m\n");
128
129         wait_for_completion(&wq_completion);
130         printk("\033[32mtest done.\033[0m\n");
131 }
132
133
134 /****************************************************************************
135  ** Test 4: Tasklets                                                       **
136  ****************************************************************************/
137 static void tasklet_func(unsigned long i)
138 {
139         printk("TASKLET: %d\n", i);
140 }
141
142
143 static DECLARE_TASKLET(low0, tasklet_func, 0);
144 static DECLARE_TASKLET(low1, tasklet_func, 1);
145 static DECLARE_TASKLET(low2, tasklet_func, 2);
146 static DECLARE_TASKLET_DISABLED(low3, tasklet_func, 3);
147
148 static DECLARE_TASKLET(hi0, tasklet_func, 10);
149 static DECLARE_TASKLET(hi1, tasklet_func, 11);
150 static DECLARE_TASKLET_DISABLED(hi2, tasklet_func, 12);
151
152
153 static void tasklet_test(void)
154 {
155         printk("BEGIN TASKLET TEST\n");
156
157         l4dde26_softirq_init();
158
159         printk("sleep 1000 msec\n");
160         msleep(1000);
161
162         printk("Scheduling tasklets 0-2 immediately. 3 is disabled for 2 seconds.\n");
163         tasklet_schedule(&low0);
164
165         tasklet_schedule(&low1);
166         tasklet_schedule(&low2);
167         tasklet_schedule(&low3);
168         msleep(2000);
169         tasklet_enable(&low3);
170
171         msleep(1000);
172         
173         printk("Scheduling hi_tasklets 10-12, and tasklets 0-2\n");
174         tasklet_hi_schedule(&hi0);
175         tasklet_hi_schedule(&hi1);
176         tasklet_hi_schedule(&hi2);
177         tasklet_schedule(&low0);
178         tasklet_schedule(&low1);
179         tasklet_schedule(&low2);
180         tasklet_enable(&hi2);
181
182         msleep(1000);
183         printk("Scheduling (disabled) tasklet 3 twice - should only run once after enabling.\n");
184         tasklet_disable(&low3);
185         tasklet_schedule(&low3);
186         tasklet_schedule(&low3);
187         tasklet_enable(&low3);
188
189         msleep(1000);
190
191         printk("END TASKLET TEST\n");
192 }
193
194
195 /******************************************************************************
196  ** Test 5: Timers                                                           **
197  **                                                                          **
198  ** Schedule a periodic timer printing "tick" every second. Additionally,    **
199  ** schedule timers for 5, 10, 15, 20, and 25 seconds. Timer at 15s will     **
200  ** deactivate the 20s timer.                                                **
201  ******************************************************************************/
202
203 static struct timer_list _timer;
204 static struct timer_list _timer5;
205 static struct timer_list _timer10;
206 static struct timer_list _timer15;
207 static struct timer_list _timer20;
208 static struct timer_list _timer25;
209
210 static void tick_func(unsigned long d)
211 {
212         printk("tick (%ld)\n", jiffies);
213         _timer.expires = jiffies + HZ;
214         add_timer(&_timer);
215 }
216
217
218 static void timer_func(unsigned long d)
219 {
220         printk("timer_func: %lu\n", d);
221
222         if (d == 15) {
223                 printk("De-scheduling 20s timer.\n");
224                 del_timer(&_timer20);
225         }
226
227         if (timer_pending(&_timer20))
228                 printk("timer for 20s still pending.\n");
229         else
230                 printk("timer for 20s has been disabled.\n");
231 }
232
233
234 static void timer_test(void)
235 {
236         l4dde26_init_timers();
237
238         printk("BEGIN TIMER TEST\n");
239 #ifdef ARCH_arm
240         printk("jiffies: %ld, HZ: %ld\n", jiffies, HZ);
241 #else
242         printk("jiffies(%p): %ld, HZ(%p): %ld\n", &jiffies, jiffies, &HZ, HZ);
243 #endif
244
245         setup_timer(&_timer, tick_func, 0);
246         _timer.expires = jiffies + HZ;
247         add_timer(&_timer);
248
249         setup_timer(&_timer5, timer_func, 5);
250         _timer5.expires = jiffies + 5*HZ;
251         setup_timer(&_timer10, timer_func, 10); 
252         _timer10.expires = jiffies + 10*HZ;
253         setup_timer(&_timer15, timer_func, 15); 
254         _timer15.expires = jiffies + 15*HZ;
255         setup_timer(&_timer20, timer_func, 20); 
256         _timer20.expires = jiffies + 20*HZ;
257         setup_timer(&_timer25, timer_func, 25); 
258         _timer25.expires = jiffies + 25*HZ;
259
260         add_timer(&_timer5);
261         add_timer(&_timer10);
262         add_timer(&_timer15);
263         add_timer(&_timer20);
264         add_timer(&_timer25);
265
266         msleep(30000);
267
268         del_timer(&_timer);
269         printk("END TIMER TEST\n");
270 }
271
272
273 /******************************
274  ** Test 6: Memory subsystem **
275  ******************************/
276
277 static void memory_kmem_cache_test(void)
278 {
279         struct kmem_cache *cache0;
280         struct obj0
281         {
282                 unsigned foo;
283                 unsigned bar;
284         };
285         static struct obj0 *p0[1024];
286
287         struct kmem_cache *cache1;
288         struct obj1
289         {
290                 char      foo[50];
291                 unsigned *bar;
292         };
293         static struct obj1 *p1[256];
294
295         cache0 = kmem_cache_create("obj0", sizeof(*p0[0]), 0, 0, 0);
296         cache1 = kmem_cache_create("obj1", sizeof(*p1[0]), 0, 0, 0);
297         printk("kmem caches: %p %p\n", cache0, cache1);
298
299         unsigned i;
300         for (i = 0; i < 1024; ++i)
301                 p0[i] = kmem_cache_alloc(cache0, i);
302
303         for (i = 0; i < 256; ++i)
304                 p1[i] = kmem_cache_alloc(cache1, i);
305
306         for (i = 256; i > 0; --i)
307                 kmem_cache_free(cache1, p1[i-1]);
308
309         for (i = 1024; i > 0; --i)
310                 kmem_cache_free(cache0, p0[i-1]);
311
312         kmem_cache_destroy(cache1);
313         kmem_cache_destroy(cache0);
314         printk("Done testing kmem_cache_alloc() & co.\n");
315 }
316
317
318 static void memory_page_alloc_test(void)
319 {
320         unsigned long p[4];
321         p[0] = __get_free_page(GFP_KERNEL);
322         p[1] = __get_free_pages(GFP_KERNEL, 1);
323         p[2] = __get_free_pages(GFP_KERNEL, 2);
324         p[3] = __get_free_pages(GFP_KERNEL, 3);
325         printk("pages: %p %p %p %p\n", p[0], p[1], p[2], p[3]);
326
327         free_pages(p[0], 0);
328         free_pages(p[1], 1);
329         free_pages(p[2], 2);
330         free_pages(p[3], 3);
331         printk("Freed pages\n");
332 }
333
334
335 static void memory_kmalloc_test(void)
336 {
337         // XXX initialized by dde26_init()!
338 //      l4dde26_kmalloc_init();
339
340         const unsigned count = 33;
341         char *p[count];
342
343         int i;
344         for (i = 0; i < count; ++i) {
345                 p[i] = kmalloc(32 + i*15, GFP_KERNEL);
346                 *p[i] = i;
347                 printk("p[%d] = %p\n", i, p[i]);
348         }
349
350         for (i = count; i > 0; --i)
351                 if (p[i-1]) kfree(p[i-1]);
352
353         for (i = 0; i < count; ++i) {
354                 p[i] = kmalloc(3000 + i*20, GFP_KERNEL);
355                 *p[i] = i;
356                 printk("p[%d] = %p\n", i, p[i]);
357         }
358
359         for (i = count; i > 0; --i)
360                 if (p[i-1]) kfree(p[i-1]);
361
362 }
363
364
365 static void memory_test(void)
366 {
367         printk("memory test\n");
368         if (1) memory_kmem_cache_test();
369         if (1) memory_page_alloc_test();
370         if (1) memory_kmalloc_test();
371         printk("End of memory test\n");
372 }
373
374
375 /****************************************************************************
376  ** Test 7: KThreads                                                       **
377  ****************************************************************************/
378 void kthread_test(void)
379 {
380 }
381
382
383 /****************************************************************************
384  ** Test 8: Work queues                                                    **
385  ****************************************************************************/
386 static void work_queue_func(struct work_struct *data);
387 static void work_queue_func2(struct work_struct *data);
388 static struct workqueue_struct *_wq;
389 static DECLARE_WORK(_wobj, work_queue_func);
390 static DECLARE_WORK(_wobj2, work_queue_func2);
391 static int wq_cnt = 0;
392
393 static void work_queue_func(struct work_struct *data)
394 {
395         printk("(1) Work queue function... Do some work here...\n");
396         if (++wq_cnt < 5)
397                 queue_work(_wq, &_wobj);
398 }
399
400
401 static void work_queue_func2(struct work_struct *data)
402 {
403         printk("(2) Work queue function 2... Do some work here...\n");
404         if (++wq_cnt < 10)
405                 schedule_work(&_wobj2);
406 }
407
408
409 static void work_queue_test(void)
410 {
411         int i;
412         printk("BEGIN WQ TEST\n");
413         _wq = create_workqueue("HelloWQ");
414         BUG_ON(_wq == NULL);
415         queue_work(_wq, &_wobj);
416         schedule_work(&_wobj2);
417         printk("END WQ TEST\n");
418 }
419
420
421 /****************************************************************************
422  ** Test 9: PCI                                                            **
423  ****************************************************************************/
424
425 void pci_test(void)
426 {
427         l4dde26_init_pci();
428 }
429
430
431 /*************************************************
432  ** Main routine (switch on desired tests here) **
433  *************************************************/
434
435 int main(int argc, const char **argv)
436 {
437         int test_current = 1;
438         int test_kernel_thread = 1;
439         int test_wait = 1;
440         int test_tasklet = 1;
441         int test_timer = 1;
442         int test_memory = 1;
443         int test_kthread = 1;
444         int test_work = 1;
445         int test_pci = 1;
446
447         msleep(1000);
448
449         if (parse_cmdline(&argc, &argv,
450                 'c', "current", "test current() function",
451                 PARSE_CMD_SWITCH, 1, &test_current,
452                 'k', "kernel-thread", "test startup of kernel threads",
453                 PARSE_CMD_SWITCH, 1, &test_kernel_thread,
454                 'w', "waitqueue", "test wait queues",
455                 PARSE_CMD_SWITCH, 1, &test_wait,
456                 't', "tasklet", "test tasklets",
457                 PARSE_CMD_SWITCH, 1, &test_tasklet,
458                 'T', "timer", "test timers",
459                 PARSE_CMD_SWITCH, 1, &test_timer,
460                 'm', "memory", "test memory management",
461                 PARSE_CMD_SWITCH, 1, &test_memory,
462                 'K', "kthread", "test kthreads",
463                 PARSE_CMD_SWITCH, 1, &test_kthread,
464                 'W', "workqueue", "test work queues",
465                 PARSE_CMD_SWITCH, 1, &test_work,
466                 'p', "pci", "test PCI stuff",
467                 PARSE_CMD_SWITCH, 1, &test_pci,
468                 0, 0))
469                 return 1;
470
471         printk("DDEKit test. Carrying out tests:\n");
472         printk("\t* current()\n");
473         printk("\t* kernel_thread()\n");
474         printk("\t* wait queues\n");
475         printk("\t* tasklets\n");
476         printk("\t* timers\n");
477         printk("\t* memory management\n");
478         printk("\t* kthreads\n");
479         printk("\t* work queues\n");
480         printk("\t* PCI subsystem\n");
481
482 #if 0
483         printk("l4dde26_init()\n");
484         l4dde26_init();
485         printk("l4dde26_process_init()\n");
486         l4dde26_process_init();
487         printk("l4dde26_do_initcalls()\n");
488         l4dde26_do_initcalls();
489 #endif
490
491         printk("Init done. Running tests.\n");
492         if (test_current) current_test();
493         if (test_kernel_thread) kernel_thread_test();
494         if (test_wait) wq_test();
495         if (test_tasklet) tasklet_test();
496         if (test_timer) timer_test();
497         if (test_memory) memory_test();
498         if (1) kthread_test();
499         if (test_work) work_queue_test();
500 //      if (test_pci) pci_test();
501         printk("Test done.\n");
502
503         l4_sleep_forever();
504
505         return 0;
506 }