Path: blob/master/tools/testing/radix-tree/iteration_check_2.c
26285 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* iteration_check_2.c: Check that deleting a tagged entry doesn't cause3* an RCU walker to finish early.4* Copyright (c) 2020 Oracle5* Author: Matthew Wilcox <[email protected]>6*/7#include <pthread.h>8#include "test.h"910static volatile bool test_complete;1112static void *iterator(void *arg)13{14XA_STATE(xas, arg, 0);15void *entry;1617rcu_register_thread();1819while (!test_complete) {20xas_set(&xas, 0);21rcu_read_lock();22xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0)23;24rcu_read_unlock();25assert(xas.xa_index >= 100);26}2728rcu_unregister_thread();29return NULL;30}3132static void *throbber(void *arg)33{34struct xarray *xa = arg;3536rcu_register_thread();3738while (!test_complete) {39int i;4041for (i = 0; i < 100; i++) {42xa_store(xa, i, xa_mk_value(i), GFP_KERNEL);43xa_set_mark(xa, i, XA_MARK_0);44}45for (i = 0; i < 100; i++)46xa_erase(xa, i);47}4849rcu_unregister_thread();50return NULL;51}5253void iteration_test2(unsigned test_duration)54{55pthread_t threads[2];56DEFINE_XARRAY(array);57int i;5859printv(1, "Running iteration test 2 for %d seconds\n", test_duration);6061test_complete = false;6263xa_store(&array, 100, xa_mk_value(100), GFP_KERNEL);64xa_set_mark(&array, 100, XA_MARK_0);6566if (pthread_create(&threads[0], NULL, iterator, &array)) {67perror("create iterator thread");68exit(1);69}70if (pthread_create(&threads[1], NULL, throbber, &array)) {71perror("create throbber thread");72exit(1);73}7475sleep(test_duration);76test_complete = true;7778for (i = 0; i < 2; i++) {79if (pthread_join(threads[i], NULL)) {80perror("pthread_join");81exit(1);82}83}8485xa_destroy(&array);86}878889