completions.c 1.6 KB

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