6
6
#include <linux/slab.h>
7
7
#include <asm/timex.h>
8
8
#include <linux/bitmap.h>
9
+ #include <linux/maple_tree.h>
9
10
10
11
#define __param (type , name , init , msg ) \
11
12
static type name = init; \
@@ -193,6 +194,121 @@ static int intersection_range_check(void)
193
194
return 0 ;
194
195
}
195
196
197
+ #ifdef CONFIG_INTERVAL_TREE_SPAN_ITER
198
+ /*
199
+ * Helper function to get span of current position from maple tree point of
200
+ * view.
201
+ */
202
+ static void mas_cur_span (struct ma_state * mas , struct interval_tree_span_iter * state )
203
+ {
204
+ unsigned long cur_start ;
205
+ unsigned long cur_last ;
206
+ int is_hole ;
207
+
208
+ if (mas -> status == ma_overflow )
209
+ return ;
210
+
211
+ /* walk to current position */
212
+ state -> is_hole = mas_walk (mas ) ? 0 : 1 ;
213
+
214
+ cur_start = mas -> index < state -> first_index ?
215
+ state -> first_index : mas -> index ;
216
+
217
+ /* whether we have followers */
218
+ do {
219
+
220
+ cur_last = mas -> last > state -> last_index ?
221
+ state -> last_index : mas -> last ;
222
+
223
+ is_hole = mas_next_range (mas , state -> last_index ) ? 0 : 1 ;
224
+
225
+ } while (mas -> status != ma_overflow && is_hole == state -> is_hole );
226
+
227
+ if (state -> is_hole ) {
228
+ state -> start_hole = cur_start ;
229
+ state -> last_hole = cur_last ;
230
+ } else {
231
+ state -> start_used = cur_start ;
232
+ state -> last_used = cur_last ;
233
+ }
234
+
235
+ /* advance position for next round */
236
+ if (mas -> status != ma_overflow )
237
+ mas_set (mas , cur_last + 1 );
238
+ }
239
+
240
+ static int span_iteration_check (void )
241
+ {
242
+ int i , j , k ;
243
+ unsigned long start , last ;
244
+ struct interval_tree_span_iter span , mas_span ;
245
+
246
+ DEFINE_MTREE (tree );
247
+
248
+ MA_STATE (mas , & tree , 0 , 0 );
249
+
250
+ printk (KERN_ALERT "interval tree span iteration\n" );
251
+
252
+ for (i = 0 ; i < search_loops ; i ++ ) {
253
+ /* Initialize interval tree for each round */
254
+ init ();
255
+ for (j = 0 ; j < nnodes ; j ++ )
256
+ interval_tree_insert (nodes + j , & root );
257
+
258
+ /* Put all the range into maple tree */
259
+ mt_init_flags (& tree , MT_FLAGS_ALLOC_RANGE );
260
+ mt_set_in_rcu (& tree );
261
+
262
+ for (j = 0 ; j < nnodes ; j ++ )
263
+ WARN_ON_ONCE (mtree_store_range (& tree , nodes [j ].start ,
264
+ nodes [j ].last , nodes + j , GFP_KERNEL ));
265
+
266
+ /* Let's try nsearches different ranges */
267
+ for (k = 0 ; k < nsearches ; k ++ ) {
268
+ /* Try whole range once */
269
+ if (!k ) {
270
+ start = 0UL ;
271
+ last = ULONG_MAX ;
272
+ } else {
273
+ last = (prandom_u32_state (& rnd ) >> 4 ) % max_endpoint ;
274
+ start = (prandom_u32_state (& rnd ) >> 4 ) % last ;
275
+ }
276
+
277
+ mas_span .first_index = start ;
278
+ mas_span .last_index = last ;
279
+ mas_span .is_hole = -1 ;
280
+ mas_set (& mas , start );
281
+
282
+ interval_tree_for_each_span (& span , & root , start , last ) {
283
+ mas_cur_span (& mas , & mas_span );
284
+
285
+ WARN_ON_ONCE (span .is_hole != mas_span .is_hole );
286
+
287
+ if (span .is_hole ) {
288
+ WARN_ON_ONCE (span .start_hole != mas_span .start_hole );
289
+ WARN_ON_ONCE (span .last_hole != mas_span .last_hole );
290
+ } else {
291
+ WARN_ON_ONCE (span .start_used != mas_span .start_used );
292
+ WARN_ON_ONCE (span .last_used != mas_span .last_used );
293
+ }
294
+ }
295
+
296
+ }
297
+
298
+ WARN_ON_ONCE (mas .status != ma_overflow );
299
+
300
+ /* Cleanup maple tree for each round */
301
+ mtree_destroy (& tree );
302
+ /* Cleanup interval tree for each round */
303
+ for (j = 0 ; j < nnodes ; j ++ )
304
+ interval_tree_remove (nodes + j , & root );
305
+ }
306
+ return 0 ;
307
+ }
308
+ #else
309
+ static inline int span_iteration_check (void ) {return 0 ; }
310
+ #endif
311
+
196
312
static int interval_tree_test_init (void )
197
313
{
198
314
nodes = kmalloc_array (nnodes , sizeof (struct interval_tree_node ),
@@ -211,6 +327,7 @@ static int interval_tree_test_init(void)
211
327
basic_check ();
212
328
search_check ();
213
329
intersection_range_check ();
330
+ span_iteration_check ();
214
331
215
332
kfree (queries );
216
333
kfree (nodes );
0 commit comments