regression4.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kernel.h>
  3. #include <linux/gfp.h>
  4. #include <linux/slab.h>
  5. #include <linux/radix-tree.h>
  6. #include <linux/rcupdate.h>
  7. #include <stdlib.h>
  8. #include <pthread.h>
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include "regression.h"
  12. static pthread_barrier_t worker_barrier;
  13. static int obj0, obj1;
  14. static RADIX_TREE(mt_tree, GFP_KERNEL);
  15. static void *reader_fn(void *arg)
  16. {
  17. int i;
  18. void *entry;
  19. rcu_register_thread();
  20. pthread_barrier_wait(&worker_barrier);
  21. for (i = 0; i < 1000000; i++) {
  22. rcu_read_lock();
  23. entry = radix_tree_lookup(&mt_tree, 0);
  24. rcu_read_unlock();
  25. if (entry != &obj0) {
  26. printf("iteration %d bad entry = %p\n", i, entry);
  27. abort();
  28. }
  29. }
  30. rcu_unregister_thread();
  31. return NULL;
  32. }
  33. static void *writer_fn(void *arg)
  34. {
  35. int i;
  36. rcu_register_thread();
  37. pthread_barrier_wait(&worker_barrier);
  38. for (i = 0; i < 1000000; i++) {
  39. radix_tree_insert(&mt_tree, 1, &obj1);
  40. radix_tree_delete(&mt_tree, 1);
  41. }
  42. rcu_unregister_thread();
  43. return NULL;
  44. }
  45. void regression4_test(void)
  46. {
  47. pthread_t reader, writer;
  48. printv(1, "regression test 4 starting\n");
  49. radix_tree_insert(&mt_tree, 0, &obj0);
  50. pthread_barrier_init(&worker_barrier, NULL, 2);
  51. if (pthread_create(&reader, NULL, reader_fn, NULL) ||
  52. pthread_create(&writer, NULL, writer_fn, NULL)) {
  53. perror("pthread_create");
  54. exit(1);
  55. }
  56. if (pthread_join(reader, NULL) || pthread_join(writer, NULL)) {
  57. perror("pthread_join");
  58. exit(1);
  59. }
  60. printv(1, "regression test 4 passed\n");
  61. }