Advertisement
Regazi

zad3

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