diff options
author | Zheng Da <zhengda1936@gmail.com> | 2010-01-14 08:54:20 +0100 |
---|---|---|
committer | Zheng Da <zhengda1936@gmail.com> | 2010-01-14 08:54:20 +0100 |
commit | 693bd3602dd8f2f6e540558d9bf6f509008dc0bc (patch) | |
tree | 888ffb492ec10ddfb98e07d7fdee474d92d87c01 | |
parent | e4d437ccb296d2e8f1bb77d7c9914bb1bf49872a (diff) |
Add the original dde26_test.
-rw-r--r-- | dde26_test/Makefile | 21 | ||||
-rw-r--r-- | dde26_test/main.c | 502 |
2 files changed, 523 insertions, 0 deletions
diff --git a/dde26_test/Makefile b/dde26_test/Makefile new file mode 100644 index 00000000..444a1f2d --- /dev/null +++ b/dde26_test/Makefile @@ -0,0 +1,21 @@ +PKGDIR ?= ../../.. +L4DIR ?= $(PKGDIR)/../.. + +SYSTEMS = x86-l4v2 + +DEFAULT_RELOC = 0x00a00000 + +-include $(PKGDIR_OBJ)/Makeconf + +ifeq ($(CONFIG_DDE26_COMMON),y) +TARGET = dde26_test +endif + +SRC_C = main.c + +LIBS += -ldde_linux26.o -lddekit -lio -llist_alloc -lparsecmdline + +# DDE configuration +include $(PKGDIR)/linux26/Makeconf + +include $(L4DIR)/mk/prog.mk diff --git a/dde26_test/main.c b/dde26_test/main.c new file mode 100644 index 00000000..88d33ba6 --- /dev/null +++ b/dde26_test/main.c @@ -0,0 +1,502 @@ +/* + * \brief DDE for Linux 2.6 test program + * \author Bjoern Doebel <doebel@os.inf.tu-dresden.de> + * \author Christian Helmuth <ch12@os.inf.tu-dresden.de> + * \date 2007-01-22 + */ + +#include <asm/current.h> + +#include <linux/kernel.h> +#include <linux/completion.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/wait.h> +#include <linux/sched.h> +#include <linux/workqueue.h> +#include <linux/interrupt.h> +//#include <linux/kthread.h> + +#include <l4/dde/dde.h> +#include <l4/dde/ddekit/initcall.h> +#include <l4/dde/linux26/dde26.h> + +#include <l4/util/parse_cmd.h> +#include <l4/util/util.h> +#include <l4/log/l4log.h> + +/* We define 4 initcalls and see if these are executed + * in the beginning. + */ +static __init void foo(void) { printk("foo module_init\n"); } +static __init void bar(void) { printk("bar device_initcall\n"); } +static __init void bla(void) { printk("bla arch_initcall\n"); } +static __init void blub(void) { printk("blub subsys_initcall\n"); } +module_init(foo); +device_initcall(bar); +arch_initcall(bla); +subsys_initcall(blub); + +/*********************************************************************** + ** Test 1: Check whether the current() macro works. ** + ***********************************************************************/ +static void current_test(void) +{ + struct task_struct *t = NULL; + + printk("Current() test.\n"); + + t = current; + printk("\tt = %p\n", t); +} + + +/*********************************************************************** + ** Test 2: Getting complicated. Test startup of some kernel threads ** + ** and wait for them to finish using completions. ** + ***********************************************************************/ +#define NUM_KTHREADS 5 +static struct completion _kthread_completions_[NUM_KTHREADS]; + +static int kernel_thread_func(void *arg) +{ + printk("\t\tKernel thread %d\n", (int)arg); + printk("\t\tcurrent = %p\n", current); + + /* do some work */ + msleep(200); + + complete_and_exit( &_kthread_completions_[(int)arg], 0 ); + return 0; +} + + +static void kernel_thread_test(void) +{ + int i; + printk("Testing kernel_thread()\n"); + for (i=0; i < NUM_KTHREADS; i++) { + int j; + printk("\tInitializing completion for kernel thread.%x\n", i+1); + init_completion(&_kthread_completions_[i]); + printk("\tStarting kthread.%x\n", i+1); + j = kernel_thread(kernel_thread_func, (void *)i, 0); + printk("\treturn: %d\n", j); + } + + for (i=0; i < NUM_KTHREADS; i++) { + printk("\tWaiting for kthread.%x to complete.\n", i+1); + wait_for_completion(&_kthread_completions_[i]); + printk("\tkthread.%x has exited.\n", i+1); + } +} + + +/****************************************************************************** + ** Test 3: Test kernel wait queues: start a thread incrementing wait_value, ** + ** and sleep until wait_value is larger than 6 for the first time. ** + ******************************************************************************/ +static DECLARE_WAIT_QUEUE_HEAD(_wq_head); +static int wait_value = 0; +static struct completion wq_completion; + +static int inc_func(void *arg) +{ + int i = 0; + + printk("\033[33mI am counting up wait_value.\033[0m\n"); + for (i=0; i<10; i++) + { + printk("\033[33mwait_value: %d\033[0m\n", ++wait_value); + wake_up(&_wq_head); + msleep(500); + } + complete_and_exit(&wq_completion, 0); +} + + +static void wq_test(void) +{ + int pid; + printk("\033[32mWait_queue test. I'm waiting vor wait_value to become >6.\033[0m\n"); + + init_completion(&wq_completion); + pid = kernel_thread(inc_func, 0, 0); + + wait_event(_wq_head, wait_value > 6); + printk("\033[32;1mwait_value > 6 occured!\033[0m\n"); + + wait_for_completion(&wq_completion); + printk("\033[32mtest done.\033[0m\n"); +} + + +/**************************************************************************** + ** Test 4: Tasklets ** + ****************************************************************************/ +static void tasklet_func(unsigned long i) +{ + printk("TASKLET: %d\n", i); +} + + +static DECLARE_TASKLET(low0, tasklet_func, 0); +static DECLARE_TASKLET(low1, tasklet_func, 1); +static DECLARE_TASKLET(low2, tasklet_func, 2); +static DECLARE_TASKLET_DISABLED(low3, tasklet_func, 3); + +static DECLARE_TASKLET(hi0, tasklet_func, 10); +static DECLARE_TASKLET(hi1, tasklet_func, 11); +static DECLARE_TASKLET_DISABLED(hi2, tasklet_func, 12); + + +static void tasklet_test(void) +{ + printk("BEGIN TASKLET TEST\n"); + + l4dde26_softirq_init(); + + printk("sleep 1000 msec\n"); + msleep(1000); + + printk("Scheduling tasklets 0-2 immediately. 3 is disabled for 2 seconds.\n"); + tasklet_schedule(&low0); + + tasklet_schedule(&low1); + tasklet_schedule(&low2); + tasklet_schedule(&low3); + msleep(2000); + tasklet_enable(&low3); + + msleep(1000); + + printk("Scheduling hi_tasklets 10-12, and tasklets 0-2\n"); + tasklet_hi_schedule(&hi0); + tasklet_hi_schedule(&hi1); + tasklet_hi_schedule(&hi2); + tasklet_schedule(&low0); + tasklet_schedule(&low1); + tasklet_schedule(&low2); + tasklet_enable(&hi2); + + msleep(1000); + printk("Scheduling (disabled) tasklet 3 twice - should only run once after enabling.\n"); + tasklet_disable(&low3); + tasklet_schedule(&low3); + tasklet_schedule(&low3); + tasklet_enable(&low3); + + msleep(1000); + + printk("END TASKLET TEST\n"); +} + + +/****************************************************************************** + ** Test 5: Timers ** + ** ** + ** Schedule a periodic timer printing "tick" every second. Additionally, ** + ** schedule timers for 5, 10, 15, 20, and 25 seconds. Timer at 15s will ** + ** deactivate the 20s timer. ** + ******************************************************************************/ + +static struct timer_list _timer; +static struct timer_list _timer5; +static struct timer_list _timer10; +static struct timer_list _timer15; +static struct timer_list _timer20; +static struct timer_list _timer25; + +static void tick_func(unsigned long d) +{ + printk("tick (%ld)\n", jiffies); + _timer.expires = jiffies + HZ; + add_timer(&_timer); +} + + +static void timer_func(unsigned long d) +{ + printk("timer_func: %lu\n", d); + + if (d == 15) { + printk("De-scheduling 20s timer.\n"); + del_timer(&_timer20); + } + + if (timer_pending(&_timer20)) + printk("timer for 20s still pending.\n"); + else + printk("timer for 20s has been disabled.\n"); +} + + +static void timer_test(void) +{ + l4dde26_init_timers(); + + printk("BEGIN TIMER TEST\n"); + printk("jiffies(%p): %ld, HZ(%p): %ld\n", &jiffies, jiffies, &HZ, HZ); + + setup_timer(&_timer, tick_func, 0); + _timer.expires = jiffies + HZ; + add_timer(&_timer); + + setup_timer(&_timer5, timer_func, 5); + _timer5.expires = jiffies + 5*HZ; + setup_timer(&_timer10, timer_func, 10); + _timer10.expires = jiffies + 10*HZ; + setup_timer(&_timer15, timer_func, 15); + _timer15.expires = jiffies + 15*HZ; + setup_timer(&_timer20, timer_func, 20); + _timer20.expires = jiffies + 20*HZ; + setup_timer(&_timer25, timer_func, 25); + _timer25.expires = jiffies + 25*HZ; + + add_timer(&_timer5); + add_timer(&_timer10); + add_timer(&_timer15); + add_timer(&_timer20); + add_timer(&_timer25); + + msleep(30000); + + del_timer(&_timer); + printk("END TIMER TEST\n"); +} + + +/****************************** + ** Test 6: Memory subsystem ** + ******************************/ + +static void memory_kmem_cache_test(void) +{ + struct kmem_cache *cache0; + struct obj0 + { + unsigned foo; + unsigned bar; + }; + static struct obj0 *p0[1024]; + + struct kmem_cache *cache1; + struct obj1 + { + char foo[50]; + unsigned *bar; + }; + static struct obj1 *p1[256]; + + cache0 = kmem_cache_create("obj0", sizeof(*p0[0]), 0, 0, 0); + cache1 = kmem_cache_create("obj1", sizeof(*p1[0]), 0, 0, 0); + printk("kmem caches: %p %p\n", cache0, cache1); + + unsigned i; + for (i = 0; i < 1024; ++i) + p0[i] = kmem_cache_alloc(cache0, i); + + for (i = 0; i < 256; ++i) + p1[i] = kmem_cache_alloc(cache1, i); + + for (i = 256; i > 0; --i) + kmem_cache_free(cache1, p1[i-1]); + + for (i = 1024; i > 0; --i) + kmem_cache_free(cache0, p0[i-1]); + + kmem_cache_destroy(cache1); + kmem_cache_destroy(cache0); + printk("Done testing kmem_cache_alloc() & co.\n"); +} + + +static void memory_page_alloc_test(void) +{ + unsigned long p[4]; + p[0] = __get_free_page(GFP_KERNEL); + p[1] = __get_free_pages(GFP_KERNEL, 1); + p[2] = __get_free_pages(GFP_KERNEL, 2); + p[3] = __get_free_pages(GFP_KERNEL, 3); + printk("pages: %p %p %p %p\n", p[0], p[1], p[2], p[3]); + + free_pages(p[0], 0); + free_pages(p[1], 1); + free_pages(p[2], 2); + free_pages(p[3], 3); + printk("Freed pages\n"); +} + + +static void memory_kmalloc_test(void) +{ + // XXX initialized by dde26_init()! +// l4dde26_kmalloc_init(); + + const unsigned count = 33; + char *p[count]; + + int i; + for (i = 0; i < count; ++i) { + p[i] = kmalloc(32 + i*15, GFP_KERNEL); + *p[i] = i; + printk("p[%d] = %p\n", i, p[i]); + } + + for (i = count; i > 0; --i) + if (p[i-1]) kfree(p[i-1]); + + for (i = 0; i < count; ++i) { + p[i] = kmalloc(3000 + i*20, GFP_KERNEL); + *p[i] = i; + printk("p[%d] = %p\n", i, p[i]); + } + + for (i = count; i > 0; --i) + if (p[i-1]) kfree(p[i-1]); + +} + + +static void memory_test(void) +{ + printk("memory test\n"); + if (1) memory_kmem_cache_test(); + if (1) memory_page_alloc_test(); + if (1) memory_kmalloc_test(); + printk("End of memory test\n"); +} + + +/**************************************************************************** + ** Test 7: KThreads ** + ****************************************************************************/ +void kthread_test(void) +{ +} + + +/**************************************************************************** + ** Test 8: Work queues ** + ****************************************************************************/ +static void work_queue_func(struct work_struct *data); +static void work_queue_func2(struct work_struct *data); +static struct workqueue_struct *_wq; +static DECLARE_WORK(_wobj, work_queue_func); +static DECLARE_WORK(_wobj2, work_queue_func2); +static int wq_cnt = 0; + +static void work_queue_func(struct work_struct *data) +{ + printk("(1) Work queue function... Do some work here...\n"); + if (++wq_cnt < 5) + queue_work(_wq, &_wobj); +} + + +static void work_queue_func2(struct work_struct *data) +{ + printk("(2) Work queue function 2... Do some work here...\n"); + if (++wq_cnt < 10) + schedule_work(&_wobj2); +} + + +static void work_queue_test(void) +{ + int i; + printk("BEGIN WQ TEST\n"); + _wq = create_workqueue("HelloWQ"); + BUG_ON(_wq == NULL); + queue_work(_wq, &_wobj); + schedule_work(&_wobj2); + printk("END WQ TEST\n"); +} + + +/**************************************************************************** + ** Test 9: PCI ** + ****************************************************************************/ + +void pci_test(void) +{ + l4dde26_init_pci(); +} + + +/************************************************* + ** Main routine (switch on desired tests here) ** + *************************************************/ + +int main(int argc, const char **argv) +{ + int test_current = 1; + int test_kernel_thread = 1; + int test_wait = 1; + int test_tasklet = 1; + int test_timer = 1; + int test_memory = 1; + int test_kthread = 1; + int test_work = 1; + int test_pci = 1; + + msleep(1000); + + if (parse_cmdline(&argc, &argv, + 'c', "current", "test current() function", + PARSE_CMD_SWITCH, 1, &test_current, + 'k', "kernel-thread", "test startup of kernel threads", + PARSE_CMD_SWITCH, 1, &test_kernel_thread, + 'w', "waitqueue", "test wait queues", + PARSE_CMD_SWITCH, 1, &test_wait, + 't', "tasklet", "test tasklets", + PARSE_CMD_SWITCH, 1, &test_tasklet, + 'T', "timer", "test timers", + PARSE_CMD_SWITCH, 1, &test_timer, + 'm', "memory", "test memory management", + PARSE_CMD_SWITCH, 1, &test_memory, + 'K', "kthread", "test kthreads", + PARSE_CMD_SWITCH, 1, &test_kthread, + 'W', "workqueue", "test work queues", + PARSE_CMD_SWITCH, 1, &test_work, + 'p', "pci", "test PCI stuff", + PARSE_CMD_SWITCH, 1, &test_pci, + 0, 0)) + return 1; + + printk("DDEKit test. Carrying out tests:\n"); + printk("\t* current()\n"); + printk("\t* kernel_thread()\n"); + printk("\t* wait queues\n"); + printk("\t* tasklets\n"); + printk("\t* timers\n"); + printk("\t* memory management\n"); + printk("\t* kthreads\n"); + printk("\t* work queues\n"); + printk("\t* PCI subsystem\n"); + +#if 0 + printk("l4dde26_init()\n"); + l4dde26_init(); + printk("l4dde26_process_init()\n"); + l4dde26_process_init(); + printk("l4dde26_do_initcalls()\n"); + l4dde26_do_initcalls(); +#endif + + printk("Init done. Running tests.\n"); + if (test_current) current_test(); + if (test_kernel_thread) kernel_thread_test(); + if (test_wait) wq_test(); + if (test_tasklet) tasklet_test(); + if (test_timer) timer_test(); + if (test_memory) memory_test(); + if (1) kthread_test(); + if (test_work) work_queue_test(); +// if (test_pci) pci_test(); + printk("Test done.\n"); + + l4_sleep_forever(); + + return 0; +} |