root/tools/testing/radix-tree/iteration_check_2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iterator
  2. throbber
  3. iteration_test2

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * iteration_check_2.c: Check that deleting a tagged entry doesn't cause
   4  * an RCU walker to finish early.
   5  * Copyright (c) 2020 Oracle
   6  * Author: Matthew Wilcox <willy@infradead.org>
   7  */
   8 #include <pthread.h>
   9 #include "test.h"
  10 
  11 static volatile bool test_complete;
  12 
  13 static void *iterator(void *arg)
  14 {
  15         XA_STATE(xas, arg, 0);
  16         void *entry;
  17 
  18         rcu_register_thread();
  19 
  20         while (!test_complete) {
  21                 xas_set(&xas, 0);
  22                 rcu_read_lock();
  23                 xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0)
  24                         ;
  25                 rcu_read_unlock();
  26                 assert(xas.xa_index >= 100);
  27         }
  28 
  29         rcu_unregister_thread();
  30         return NULL;
  31 }
  32 
  33 static void *throbber(void *arg)
  34 {
  35         struct xarray *xa = arg;
  36 
  37         rcu_register_thread();
  38 
  39         while (!test_complete) {
  40                 int i;
  41 
  42                 for (i = 0; i < 100; i++) {
  43                         xa_store(xa, i, xa_mk_value(i), GFP_KERNEL);
  44                         xa_set_mark(xa, i, XA_MARK_0);
  45                 }
  46                 for (i = 0; i < 100; i++)
  47                         xa_erase(xa, i);
  48         }
  49 
  50         rcu_unregister_thread();
  51         return NULL;
  52 }
  53 
  54 void iteration_test2(unsigned test_duration)
  55 {
  56         pthread_t threads[2];
  57         DEFINE_XARRAY(array);
  58         int i;
  59 
  60         printv(1, "Running iteration test 2 for %d seconds\n", test_duration);
  61 
  62         test_complete = false;
  63 
  64         xa_store(&array, 100, xa_mk_value(100), GFP_KERNEL);
  65         xa_set_mark(&array, 100, XA_MARK_0);
  66 
  67         if (pthread_create(&threads[0], NULL, iterator, &array)) {
  68                 perror("create iterator thread");
  69                 exit(1);
  70         }
  71         if (pthread_create(&threads[1], NULL, throbber, &array)) {
  72                 perror("create throbber thread");
  73                 exit(1);
  74         }
  75 
  76         sleep(test_duration);
  77         test_complete = true;
  78 
  79         for (i = 0; i < 2; i++) {
  80                 if (pthread_join(threads[i], NULL)) {
  81                         perror("pthread_join");
  82                         exit(1);
  83                 }
  84         }
  85 
  86         xa_destroy(&array);
  87 }

/* [<][>][^][v][top][bottom][index][help] */