completions.c 2.0 KB

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