#include #include #include #include #include #include #include #include #include #include static spinlock_t t1 = SPIN_LOCK_UNLOCKED(t1); static spinlock_t t2 = SPIN_LOCK_UNLOCKED(t2); struct task_struct *threads[3]; static int run1(void *data) { printk("thread 1 running\n"); spin_lock(&t2); printk("thread 1 got lock t2\n"); spin_lock(&t1); printk("thread 1 got lock t1\n"); spin_unlock(&t1); spin_unlock(&t2); return 0; } static int run2(void *data) { printk("thread 2 running\n"); spin_lock(&t1); printk("thread 2 got lock t1\n"); spin_unlock(&t1); return 0; } static int run3(void *data) { printk("thread 3 running\n"); spin_lock(&t2); printk("thread 3 got lock t2\n"); spin_unlock(&t2); return 0; } static int pi_test_init(void) { struct sched_param param = {.sched_priority = 10 }; int n = 0; int i; printk("set sched myself\n"); sched_setscheduler(current, SCHED_FIFO, (struct sched_param __user*)¶m); threads[n++] = kthread_create(run1, NULL, "thread1"); threads[n++] = kthread_create(run2, NULL, "thread2"); threads[n++] = kthread_create(run3, NULL, "thread3"); spin_lock(&t1); for (i=0; i < n; i++) { param.sched_priority++; printk("set sched for thread[%d] %d\n",i,threads[i]->pid); sched_setscheduler(threads[i], SCHED_FIFO, (struct sched_param __user*)¶m); } /* first wake the middle process */ wake_up_process(threads[1]); msleep(10); /* wake the lowest process that will block on the previous */ wake_up_process(threads[0]); msleep(10); /* now wake the highest process which will block on the lowest * but lets see who gets the lock when we let it go */ wake_up_process(threads[2]); msleep(10); /* let the games begin! */ printk("parent releasing the t1 lock!\n"); spin_unlock(&t1); return 0; } static void pi_test_exit(void) { } module_init(pi_test_init); module_exit(pi_test_exit); MODULE_LICENSE("GPL");