162306a36Sopenharmony_ci// SPDX-License-Identifier: LGPL-2.1
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Basic test coverage for critical regions and rseq_current_cpu().
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#define _GNU_SOURCE
762306a36Sopenharmony_ci#include <assert.h>
862306a36Sopenharmony_ci#include <sched.h>
962306a36Sopenharmony_ci#include <signal.h>
1062306a36Sopenharmony_ci#include <stdio.h>
1162306a36Sopenharmony_ci#include <string.h>
1262306a36Sopenharmony_ci#include <sys/time.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "rseq.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_civoid test_cpu_pointer(void)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	cpu_set_t affinity, test_affinity;
1962306a36Sopenharmony_ci	int i;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	sched_getaffinity(0, sizeof(affinity), &affinity);
2262306a36Sopenharmony_ci	CPU_ZERO(&test_affinity);
2362306a36Sopenharmony_ci	for (i = 0; i < CPU_SETSIZE; i++) {
2462306a36Sopenharmony_ci		if (CPU_ISSET(i, &affinity)) {
2562306a36Sopenharmony_ci			int node;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci			CPU_SET(i, &test_affinity);
2862306a36Sopenharmony_ci			sched_setaffinity(0, sizeof(test_affinity),
2962306a36Sopenharmony_ci					&test_affinity);
3062306a36Sopenharmony_ci			assert(sched_getcpu() == i);
3162306a36Sopenharmony_ci			assert(rseq_current_cpu() == i);
3262306a36Sopenharmony_ci			assert(rseq_current_cpu_raw() == i);
3362306a36Sopenharmony_ci			assert(rseq_cpu_start() == i);
3462306a36Sopenharmony_ci			node = rseq_fallback_current_node();
3562306a36Sopenharmony_ci			assert(rseq_current_node_id() == node);
3662306a36Sopenharmony_ci			CPU_CLR(i, &test_affinity);
3762306a36Sopenharmony_ci		}
3862306a36Sopenharmony_ci	}
3962306a36Sopenharmony_ci	sched_setaffinity(0, sizeof(affinity), &affinity);
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciint main(int argc, char **argv)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	if (rseq_register_current_thread()) {
4562306a36Sopenharmony_ci		fprintf(stderr, "Error: rseq_register_current_thread(...) failed(%d): %s\n",
4662306a36Sopenharmony_ci			errno, strerror(errno));
4762306a36Sopenharmony_ci		goto init_thread_error;
4862306a36Sopenharmony_ci	}
4962306a36Sopenharmony_ci	printf("testing current cpu\n");
5062306a36Sopenharmony_ci	test_cpu_pointer();
5162306a36Sopenharmony_ci	if (rseq_unregister_current_thread()) {
5262306a36Sopenharmony_ci		fprintf(stderr, "Error: rseq_unregister_current_thread(...) failed(%d): %s\n",
5362306a36Sopenharmony_ci			errno, strerror(errno));
5462306a36Sopenharmony_ci		goto init_thread_error;
5562306a36Sopenharmony_ci	}
5662306a36Sopenharmony_ci	return 0;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciinit_thread_error:
5962306a36Sopenharmony_ci	return -1;
6062306a36Sopenharmony_ci}
61