wait_queue2.c 1.7 KB

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