interval_tree_test.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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 root = RB_ROOT;
  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 *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(nnodes * sizeof(struct interval_tree_node), GFP_KERNEL);
  54. if (!nodes)
  55. return -ENOMEM;
  56. queries = kmalloc(nsearches * sizeof(int), GFP_KERNEL);
  57. if (!queries) {
  58. kfree(nodes);
  59. return -ENOMEM;
  60. }
  61. printk(KERN_ALERT "interval tree insert/remove");
  62. prandom_seed_state(&rnd, 3141592653589793238ULL);
  63. init();
  64. time1 = get_cycles();
  65. for (i = 0; i < perf_loops; i++) {
  66. for (j = 0; j < nnodes; j++)
  67. interval_tree_insert(nodes + j, &root);
  68. for (j = 0; j < nnodes; j++)
  69. interval_tree_remove(nodes + j, &root);
  70. }
  71. time2 = get_cycles();
  72. time = time2 - time1;
  73. time = div_u64(time, perf_loops);
  74. printk(" -> %llu cycles\n", (unsigned long long)time);
  75. printk(KERN_ALERT "interval tree search");
  76. for (j = 0; j < nnodes; j++)
  77. interval_tree_insert(nodes + j, &root);
  78. time1 = get_cycles();
  79. results = 0;
  80. for (i = 0; i < search_loops; i++)
  81. for (j = 0; j < nsearches; j++) {
  82. unsigned long start = search_all ? 0 : queries[j];
  83. unsigned long last = search_all ? max_endpoint : queries[j];
  84. results += search(&root, start, last);
  85. }
  86. time2 = get_cycles();
  87. time = time2 - time1;
  88. time = div_u64(time, search_loops);
  89. results = div_u64(results, search_loops);
  90. printk(" -> %llu cycles (%lu results)\n",
  91. (unsigned long long)time, results);
  92. kfree(queries);
  93. kfree(nodes);
  94. return -EAGAIN; /* Fail will directly unload the module */
  95. }
  96. static void interval_tree_test_exit(void)
  97. {
  98. printk(KERN_ALERT "test exit\n");
  99. }
  100. module_init(interval_tree_test_init)
  101. module_exit(interval_tree_test_exit)
  102. MODULE_LICENSE("GPL");
  103. MODULE_AUTHOR("Michel Lespinasse");
  104. MODULE_DESCRIPTION("Interval Tree test");