On 12/12/05 03:02, Thomas Gleixner wrote: > The rebased version of the high resolution patches on top of the > hrtimers base patch is available from the new project home: > > http://www.tglx.de/projetcs/hrtimers > > The current patch is available here: > > http://www.tglx.de/projects/hrtimers/2.6.15-rc5/patch-2.6.15-rc5-hrt2.patch This is a simple module to start a hrtimer about 20k times a second. I don't see a way to correctly restart a hrtimer or set one to be periodic so this is inefficiently bouncing between two timers. Calling restart_hrtimer() from within the hrtimer.function causes a panic. I was wondering what the correct method would be. I had to export some symbols from hrtimer.c so I could build this as a module. /* * * A simple module that starts a hrtimer ~20k/sec * * This software is available to you under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree. * */ #include #include #include #include #include #include #include #include #include #include #include #include MODULE_AUTHOR("Jeff Carr"); MODULE_DESCRIPTION("simple hrtimer test"); MODULE_LICENSE("GPL"); static struct workqueue_struct *testwq; static struct work_struct testwork; static struct hrtimer restart_hrtimer; static struct hrtimer trigger_hrtimer; static int done = 0; static int hrtimer_count = 0; #define HT_TEST_PERIOD 20000; // In nanoseconds static void do_test_work(void *data) { restart_hrtimer.expires.tv64 = (u64) HT_TEST_PERIOD; hrtimer_start(&restart_hrtimer, restart_hrtimer.expires, HRTIMER_REL); return; } static int do_restart_hrtimer(void *data) { if (!done) { trigger_hrtimer.expires.tv64 = (u64) HT_TEST_PERIOD; hrtimer_start(&trigger_hrtimer, trigger_hrtimer.expires, HRTIMER_REL); } return 0; } static int do_trigger_hrtimer(void *data) { static struct timeval now; ++hrtimer_count; do_gettimeofday(&now); if (printk_ratelimit()) printk(KERN_DEBUG "do_trigger_hrtimer() ran %d times (%li.%li)\n", hrtimer_count, now.tv_sec, now.tv_usec); if (!done) { restart_hrtimer.expires.tv64 = (u64) HT_TEST_PERIOD; hrtimer_start(&restart_hrtimer, restart_hrtimer.expires, HRTIMER_REL); } return 0; } static int __init hrtimer_test_init(void) { testwq = create_singlethread_workqueue("simple_hrtimer_test"); if (!testwq) return -1; INIT_WORK(&testwork, do_test_work, NULL); hrtimer_init(&restart_hrtimer, (const clockid_t)CLOCK_REALTIME); restart_hrtimer.data = (unsigned long)NULL; restart_hrtimer.function = do_restart_hrtimer; hrtimer_init(&trigger_hrtimer, (const clockid_t)CLOCK_REALTIME); trigger_hrtimer.data = (unsigned long)NULL; trigger_hrtimer.function = do_trigger_hrtimer; queue_work(testwq, &testwork); return 0; } static void __exit hrtimer_test_cleanup(void) { done = 1; flush_workqueue(testwq); destroy_workqueue(testwq); // not sure how to destroy this correctly hrtimer_cancel(&restart_hrtimer); remove_hrtimer(&restart_hrtimer); // not sure how to destroy this correctly hrtimer_cancel(&trigger_hrtimer); remove_hrtimer(&trigger_hrtimer); } module_init(hrtimer_test_init); module_exit(hrtimer_test_cleanup);