Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
530
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.21 KB | None | 0 0
  1. #include<linux/module.h>
  2. #include<linux/kthread.h>
  3. #include<linux/wait.h>
  4. #include<linux/slab.h>
  5. #include<linux/rcupdate.h>
  6.  
  7. enum thread_index {WAKING_THREAD, WRITER_THREAD, FIRST_READER_THREAD, SECOND_READER_THREAD};
  8.  
  9. static struct thread_structure
  10. {
  11. struct task_struct *thread[4];
  12. struct rcu_head rcu_head;
  13.  
  14.  
  15. } threads;
  16.  
  17. static wait_queue_head_t wait_queue;
  18. static bool condition;
  19. static int *number_pointer;
  20. static const int first_reader_number = 1, second_thread_number = 2;
  21.  
  22.  
  23. static void free_node(struct rcu_head *head)
  24. {
  25. struct thread_structure *node = container_of(head, struct thread_structure, rcu_head);
  26.  
  27. kfree(node);
  28. }
  29.  
  30. static int reader_thread(void *data)
  31. {
  32. int *local_number_pointer = NULL;
  33. for(;;) {
  34. rcu_read_lock();
  35. local_number_pointer = rcu_dereference(number_pointer);
  36. if(local_number_pointer)
  37. pr_info("[reader_number: %d] Value of \"number\" variable: %d\n", *(int *)data,*local_number_pointer);
  38. rcu_read_unlock();
  39. if(kthread_should_stop())
  40. return 0;
  41. set_current_state(TASK_INTERRUPTIBLE);
  42. if(schedule_timeout(HZ>>2))
  43. pr_info("Signal received!\n");
  44. }
  45. }
  46.  
  47. static int writer_thread(void *data)
  48. {
  49. int *local_number_pointer = NULL;
  50. int number = 0;
  51. DEFINE_WAIT(wait);
  52. for(;;) {
  53. void *old_pointer = NULL;
  54. local_number_pointer = kmalloc(sizeof(int),GFP_KERNEL);
  55. if(IS_ERR(local_number_pointer)) {
  56. pr_alert("Error allocating memory: %ld\n",PTR_ERR(local_number_pointer));
  57. return 0;
  58. }
  59. *local_number_pointer = number++;
  60. old_pointer = number_pointer;
  61.  
  62. rcu_assign_pointer(number_pointer,local_number_pointer);
  63. synchronize_rcu();
  64.  
  65. call_rcu(threads.rcu_head, free_node);
  66.  
  67. if(old_pointer)
  68. kfree(old_pointer);
  69. add_wait_queue(&wait_queue,&wait);
  70. while(!condition) {
  71. prepare_to_wait(&wait_queue,&wait,TASK_INTERRUPTIBLE);
  72. if(kthread_should_stop())
  73. return 0;
  74. pr_info("[writer_thread]: awake\n");
  75. schedule();
  76. }
  77. condition=false;
  78. finish_wait(&wait_queue,&wait);
  79. }
  80. }
  81.  
  82. static int waking_thread(void *data)
  83. {
  84. for(;;) {
  85. if(kthread_should_stop())
  86. return 0;
  87. set_current_state(TASK_INTERRUPTIBLE);
  88. if(schedule_timeout(HZ))
  89. pr_info("Signal received!\n");
  90. condition=true;
  91. wake_up(&wait_queue);
  92. }
  93.  
  94. }
  95.  
  96. static int __init threads_init(void)
  97. {
  98. init_waitqueue_head(&wait_queue);
  99. threads.thread[WRITER_THREAD] = kthread_run(writer_thread,NULL,"writer_thread");
  100. threads.thread[WAKING_THREAD] = kthread_run(waking_thread,NULL,"waking_thread");
  101. threads.thread[FIRST_READER_THREAD] = kthread_run(reader_thread,(void *)&first_reader_number,"first_reader_thread");
  102. threads.thread[SECOND_READER_THREAD] = kthread_run(reader_thread,(void *)&second_thread_number,"second_reader_thread");
  103. return 0;
  104. }
  105.  
  106. static void __exit threads_exit(void)
  107. {
  108. kthread_stop(threads.thread[WAKING_THREAD]);
  109. kthread_stop(threads.thread[WRITER_THREAD]);
  110. kthread_stop(threads.thread[FIRST_READER_THREAD]);
  111. kthread_stop(threads.thread[SECOND_READER_THREAD]);
  112. }
  113.  
  114. module_init(threads_init);
  115. module_exit(threads_exit);
  116.  
  117. MODULE_LICENSE("GPL");
  118. MODULE_DESCRIPTION("An example of using the kernel linux threads and an RCU mechanism.");
  119. MODULE_AUTHOR("Arkadiusz Chrobot <a.chrobot@tu.kielce.pl>");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement