/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
 * Copyright (c) 2024 David Vernet <dvernet@meta.com>
 */
#include <bpf/bpf.h>
#include <pthread.h>
#include <scx/common.h>
#include <sys/wait.h>
#include <unistd.h>
#include "maximal.bpf.skel.h"
#include "scx_test.h"

static struct maximal *skel;
static pthread_t threads[2];

bool force_exit = false;

static enum scx_test_status setup(void **ctx)
{
	skel = maximal__open();
	SCX_FAIL_IF(!skel, "Failed to open");
	SCX_ENUM_INIT(skel);
	SCX_FAIL_IF(maximal__load(skel), "Failed to load skel");

	return SCX_TEST_PASS;
}

static void *do_reload_loop(void *arg)
{
	u32 i;

	for (i = 0; i < 1024 && !force_exit; i++) {
		struct bpf_link *link;

		link = bpf_map__attach_struct_ops(skel->maps.maximal_ops);
		if (link)
			bpf_link__destroy(link);
	}

	return NULL;
}

static enum scx_test_status run(void *ctx)
{
	int err;
	void *ret;

	err = pthread_create(&threads[0], NULL, do_reload_loop, NULL);
	SCX_FAIL_IF(err, "Failed to create thread 0");

	err = pthread_create(&threads[1], NULL, do_reload_loop, NULL);
	SCX_FAIL_IF(err, "Failed to create thread 1");

	SCX_FAIL_IF(pthread_join(threads[0], &ret), "thread 0 failed");
	SCX_FAIL_IF(pthread_join(threads[1], &ret), "thread 1 failed");

	return SCX_TEST_PASS;
}

static void cleanup(void *ctx)
{
	force_exit = true;
	maximal__destroy(skel);
}

struct scx_test reload_loop = {
	.name = "reload_loop",
	.description = "Stress test loading and unloading schedulers repeatedly in a tight loop",
	.setup = setup,
	.run = run,
	.cleanup = cleanup,
};
REGISTER_SCX_TEST(&reload_loop)
