completions.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/kthread.h>
  5. #include <linux/completion.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 =
  31. kthread_create(machine_crank_thread,
  32. NULL, "KThread Crank");
  33. if (IS_ERR(crank_thread))
  34. goto ERROR_THREAD_1;
  35. flywheel_thread =
  36. kthread_create(machine_flywheel_spinup_thread,
  37. NULL, "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. 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_AUTHOR("Bob Mottram");
  57. MODULE_DESCRIPTION("Completions example");
  58. MODULE_LICENSE("GPL");