Advertisement
Guest User

zad3SO2

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