wait_queue2.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* https://cirosantilli.com/linux-kernel-module-cheat#wait-queues */
  2. #include <linux/delay.h> /* usleep_range */
  3. #include <linux/kernel.h>
  4. #include <linux/kthread.h>
  5. #include <linux/module.h>
  6. #include <linux/wait.h> /* wait_queue_head_t, wait_event_interruptible, wake_up_interruptible */
  7. static struct task_struct *kthread_wake;
  8. static struct task_struct *kthread_sleep1;
  9. static struct task_struct *kthread_sleep2;
  10. static wait_queue_head_t queue;
  11. static atomic_t awake1 = ATOMIC_INIT(0);
  12. static atomic_t awake2 = ATOMIC_INIT(0);
  13. static int kthread_wake_func(void *data)
  14. {
  15. unsigned int i = 0;
  16. while (!kthread_should_stop()) {
  17. pr_info("0 %u\n", i);
  18. usleep_range(1000000, 1000001);
  19. atomic_set(&awake1, 1);
  20. atomic_set(&awake2, 1);
  21. wake_up(&queue);
  22. i++;
  23. }
  24. return 0;
  25. }
  26. static int kthread_sleep_func_1(void *data)
  27. {
  28. unsigned int i = 0;
  29. while (!kthread_should_stop()) {
  30. pr_info("1 %u\n", i);
  31. i++;
  32. wait_event(queue, atomic_read(&awake1));
  33. atomic_set(&awake1, 0);
  34. schedule();
  35. }
  36. return 0;
  37. }
  38. static int kthread_sleep_func_2(void *data)
  39. {
  40. unsigned int i = 0;
  41. while (!kthread_should_stop()) {
  42. pr_info("2 %u\n", i);
  43. i++;
  44. wait_event(queue, atomic_read(&awake2));
  45. atomic_set(&awake2, 0);
  46. schedule();
  47. }
  48. return 0;
  49. }
  50. int init_module(void)
  51. {
  52. init_waitqueue_head(&queue);
  53. kthread_wake = kthread_create(kthread_wake_func, NULL, "wake");
  54. kthread_sleep1 = kthread_create(kthread_sleep_func_1, NULL, "sleep1");
  55. kthread_sleep2 = kthread_create(kthread_sleep_func_2, NULL, "sleep2");
  56. wake_up_process(kthread_wake);
  57. wake_up_process(kthread_sleep1);
  58. wake_up_process(kthread_sleep2);
  59. return 0;
  60. }
  61. void cleanup_module(void)
  62. {
  63. kthread_stop(kthread_sleep2);
  64. kthread_stop(kthread_sleep1);
  65. kthread_stop(kthread_wake);
  66. }
  67. MODULE_LICENSE("GPL");