tools/testing/radix-tree/regression1.c

Source file repositories/reference/linux-study-clean/tools/testing/radix-tree/regression1.c

File Facts

System
Linux kernel
Corpus path
tools/testing/radix-tree/regression1.c
Extension
.c
Size
4593 bytes
Lines
201
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct page {
	pthread_mutex_t lock;
	struct rcu_head rcu;
	int count;
	unsigned long index;
};

static struct page *page_alloc(int index)
{
	struct page *p;
	p = malloc(sizeof(struct page));
	p->count = 1;
	p->index = index;
	pthread_mutex_init(&p->lock, NULL);

	return p;
}

static void page_rcu_free(struct rcu_head *rcu)
{
	struct page *p = container_of(rcu, struct page, rcu);
	assert(!p->count);
	pthread_mutex_destroy(&p->lock);
	free(p);
}

static void page_free(struct page *p)
{
	call_rcu(&p->rcu, page_rcu_free);
}

static unsigned find_get_pages(unsigned long start,
			    unsigned int nr_pages, struct page **pages)
{
	XA_STATE(xas, &mt_tree, start);
	struct page *page;
	unsigned int ret = 0;

	rcu_read_lock();
	xas_for_each(&xas, page, ULONG_MAX) {
		if (xas_retry(&xas, page))
			continue;

		pthread_mutex_lock(&page->lock);
		if (!page->count)
			goto unlock;

		/* don't actually update page refcount */
		pthread_mutex_unlock(&page->lock);

		/* Has the page moved? */
		if (unlikely(page != xas_reload(&xas)))
			goto put_page;

		pages[ret] = page;
		ret++;
		continue;
unlock:
		pthread_mutex_unlock(&page->lock);
put_page:
		xas_reset(&xas);
	}
	rcu_read_unlock();
	return ret;
}

static pthread_barrier_t worker_barrier;

static void *regression1_fn(void *arg)
{
	rcu_register_thread();

	if (pthread_barrier_wait(&worker_barrier) ==
			PTHREAD_BARRIER_SERIAL_THREAD) {
		int j;

		for (j = 0; j < 1000000; j++) {
			struct page *p;

			p = page_alloc(0);
			xa_lock(&mt_tree);
			radix_tree_insert(&mt_tree, 0, p);
			xa_unlock(&mt_tree);

			p = page_alloc(1);
			xa_lock(&mt_tree);
			radix_tree_insert(&mt_tree, 1, p);
			xa_unlock(&mt_tree);

			xa_lock(&mt_tree);

Annotation

Implementation Notes