completions.c 1.7 KB

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