1
0

completions.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * completions.c
  3. */
  4. #include <linux/completion.h>
  5. #include <linux/err.h> /* for IS_ERR() */
  6. #include <linux/init.h>
  7. #include <linux/kthread.h>
  8. #include <linux/module.h>
  9. #include <linux/printk.h>
  10. #include <linux/version.h>
  11. static struct completion crank_comp;
  12. static struct completion flywheel_comp;
  13. static int machine_crank_thread(void *arg)
  14. {
  15. pr_info("Turn the crank\n");
  16. complete_all(&crank_comp);
  17. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
  18. kthread_complete_and_exit(&crank_comp, 0);
  19. #else
  20. complete_and_exit(&crank_comp, 0);
  21. #endif
  22. }
  23. static int machine_flywheel_spinup_thread(void *arg)
  24. {
  25. wait_for_completion(&crank_comp);
  26. pr_info("Flywheel spins up\n");
  27. complete_all(&flywheel_comp);
  28. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
  29. kthread_complete_and_exit(&flywheel_comp, 0);
  30. #else
  31. complete_and_exit(&flywheel_comp, 0);
  32. #endif
  33. }
  34. static int __init completions_init(void)
  35. {
  36. struct task_struct *crank_thread;
  37. struct task_struct *flywheel_thread;
  38. pr_info("completions example\n");
  39. init_completion(&crank_comp);
  40. init_completion(&flywheel_comp);
  41. crank_thread = kthread_create(machine_crank_thread, NULL, "KThread Crank");
  42. if (IS_ERR(crank_thread))
  43. goto ERROR_THREAD_1;
  44. flywheel_thread = kthread_create(machine_flywheel_spinup_thread, NULL,
  45. "KThread Flywheel");
  46. if (IS_ERR(flywheel_thread))
  47. goto ERROR_THREAD_2;
  48. wake_up_process(flywheel_thread);
  49. wake_up_process(crank_thread);
  50. return 0;
  51. ERROR_THREAD_2:
  52. kthread_stop(crank_thread);
  53. ERROR_THREAD_1:
  54. return -1;
  55. }
  56. static void __exit completions_exit(void)
  57. {
  58. wait_for_completion(&crank_comp);
  59. wait_for_completion(&flywheel_comp);
  60. pr_info("completions exit\n");
  61. }
  62. module_init(completions_init);
  63. module_exit(completions_exit);
  64. MODULE_DESCRIPTION("Completions example");
  65. MODULE_LICENSE("GPL");