interval_tree_test.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include <linux/module.h>
  2. #include <linux/moduleparam.h>
  3. #include <linux/interval_tree.h>
  4. #include <linux/random.h>
  5. #include <linux/slab.h>
  6. #include <asm/timex.h>
  7. #define __param(type, name, init, msg) \
  8. static type name = init; \
  9. module_param(name, type, 0444); \
  10. MODULE_PARM_DESC(name, msg);
  11. __param(int, nnodes, 100, "Number of nodes in the interval tree");
  12. __param(int, perf_loops, 1000, "Number of iterations modifying the tree");
  13. __param(int, nsearches, 100, "Number of searches to the interval tree");
  14. __param(int, search_loops, 1000, "Number of iterations searching the tree");
  15. __param(bool, search_all, false, "Searches will iterate all nodes in the tree");
  16. __param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint");
  17. static struct rb_root_cached root = RB_ROOT_CACHED;
  18. static struct interval_tree_node *nodes = NULL;
  19. static u32 *queries = NULL;
  20. static struct rnd_state rnd;
  21. static inline unsigned long
  22. search(struct rb_root_cached *root, unsigned long start, unsigned long last)
  23. {
  24. struct interval_tree_node *node;
  25. unsigned long results = 0;
  26. for (node = interval_tree_iter_first(root, start, last); node;
  27. node = interval_tree_iter_next(node, start, last))
  28. results++;
  29. return results;
  30. }
  31. static void init(void)
  32. {
  33. int i;
  34. for (i = 0; i < nnodes; i++) {
  35. u32 b = (prandom_u32_state(&rnd) >> 4) % max_endpoint;
  36. u32 a = (prandom_u32_state(&rnd) >> 4) % b;
  37. nodes[i].start = a;
  38. nodes[i].last = b;
  39. }
  40. /*
  41. * Limit the search scope to what the user defined.
  42. * Otherwise we are merely measuring empty walks,
  43. * which is pointless.
  44. */
  45. for (i = 0; i < nsearches; i++)
  46. queries[i] = (prandom_u32_state(&rnd) >> 4) % max_endpoint;
  47. }
  48. static int interval_tree_test_init(void)
  49. {
  50. int i, j;
  51. unsigned long results;
  52. cycles_t time1, time2, time;
  53. nodes = kmalloc_array(nnodes, sizeof(struct interval_tree_node),
  54. GFP_KERNEL);
  55. if (!nodes)
  56. return -ENOMEM;
  57. queries = kmalloc_array(nsearches, sizeof(int), GFP_KERNEL);
  58. if (!queries) {
  59. kfree(nodes);
  60. return -ENOMEM;
  61. }
  62. printk(KERN_ALERT "interval tree insert/remove");
  63. prandom_seed_state(&rnd, 3141592653589793238ULL);
  64. init();
  65. time1 = get_cycles();
  66. for (i = 0; i < perf_loops; i++) {
  67. for (j = 0; j < nnodes; j++)
  68. interval_tree_insert(nodes + j, &root);
  69. for (j = 0; j < nnodes; j++)
  70. interval_tree_remove(nodes + j, &root);
  71. }
  72. time2 = get_cycles();
  73. time = time2 - time1;
  74. time = div_u64(time, perf_loops);
  75. printk(" -> %llu cycles\n", (unsigned long long)time);
  76. printk(KERN_ALERT "interval tree search");
  77. for (j = 0; j < nnodes; j++)
  78. interval_tree_insert(nodes + j, &root);
  79. time1 = get_cycles();
  80. results = 0;
  81. for (i = 0; i < search_loops; i++)
  82. for (j = 0; j < nsearches; j++) {
  83. unsigned long start = search_all ? 0 : queries[j];
  84. unsigned long last = search_all ? max_endpoint : queries[j];
  85. results += search(&root, start, last);
  86. }
  87. time2 = get_cycles();
  88. time = time2 - time1;
  89. time = div_u64(time, search_loops);
  90. results = div_u64(results, search_loops);
  91. printk(" -> %llu cycles (%lu results)\n",
  92. (unsigned long long)time, results);
  93. kfree(queries);
  94. kfree(nodes);
  95. return -EAGAIN; /* Fail will directly unload the module */
  96. }
  97. static void interval_tree_test_exit(void)
  98. {
  99. printk(KERN_ALERT "test exit\n");
  100. }
  101. module_init(interval_tree_test_init)
  102. module_exit(interval_tree_test_exit)
  103. MODULE_LICENSE("GPL");
  104. MODULE_AUTHOR("Michel Lespinasse");
  105. MODULE_DESCRIPTION("Interval Tree test");