File Index
Files and directories
Sign in
FILE

futex.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/timens/futex.c C
  1// SPDX-License-Identifier: GPL-2.0
  2#define _GNU_SOURCE
  3#include <sched.h>
  4
  5#include <linux/unistd.h>
  6#include <linux/futex.h>
  7#include <stdio.h>
  8#include <string.h>
  9#include <sys/syscall.h>
 10#include <sys/types.h>
 11#include <sys/wait.h>
 12#include <time.h>
 13#include <unistd.h>
 14
 15#include "log.h"
 16#include "timens.h"
 17
 18#define NSEC_PER_SEC 1000000000ULL
 19
 20static int run_test(int clockid)
 21{
 22	int futex_op = FUTEX_WAIT_BITSET;
 23	struct timespec timeout, end;
 24	int val = 0;
 25
 26	if (clockid == CLOCK_REALTIME)
 27		futex_op |= FUTEX_CLOCK_REALTIME;
 28
 29	clock_gettime(clockid, &timeout);
 30	timeout.tv_nsec += NSEC_PER_SEC / 10; // 100ms
 31	if (timeout.tv_nsec > NSEC_PER_SEC) {
 32		timeout.tv_sec++;
 33		timeout.tv_nsec -= NSEC_PER_SEC;
 34	}
 35
 36	if (syscall(__NR_futex, &val, futex_op, 0,
 37		    &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
 38		ksft_test_result_fail("futex didn't return ETIMEDOUT\n");
 39		return 1;
 40	}
 41
 42	if (errno != ETIMEDOUT) {
 43		ksft_test_result_fail("futex didn't return ETIMEDOUT: %s\n",
 44							strerror(errno));
 45		return 1;
 46	}
 47
 48	clock_gettime(clockid, &end);
 49
 50	if (end.tv_sec < timeout.tv_sec ||
 51	    (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_nsec)) {
 52		ksft_test_result_fail("futex slept less than 100ms\n");
 53		return 1;
 54	}
 55
 56
 57	ksft_test_result_pass("futex with the %d clockid\n", clockid);
 58
 59	return 0;
 60}
 61
 62int main(int argc, char *argv[])
 63{
 64	int status, len, fd;
 65	char buf[4096];
 66	pid_t pid;
 67	struct timespec mtime_now;
 68
 69	ksft_print_header();
 70
 71	nscheck();
 72
 73	ksft_set_plan(2);
 74
 75	clock_gettime(CLOCK_MONOTONIC, &mtime_now);
 76
 77	if (unshare_timens())
 78		return 1;
 79
 80	len = snprintf(buf, sizeof(buf), "%d %d 0",
 81			CLOCK_MONOTONIC, 70 * 24 * 3600);
 82	fd = open("/proc/self/timens_offsets", O_WRONLY);
 83	if (fd < 0)
 84		return pr_perror("/proc/self/timens_offsets");
 85
 86	if (write(fd, buf, len) != len)
 87		return pr_perror("/proc/self/timens_offsets");
 88
 89	close(fd);
 90
 91	pid = fork();
 92	if (pid < 0)
 93		return pr_perror("Unable to fork");
 94	if (pid == 0) {
 95		int ret = 0;
 96
 97		ret |= run_test(CLOCK_REALTIME);
 98		ret |= run_test(CLOCK_MONOTONIC);
 99		if (ret)
100			ksft_exit_fail();
101		ksft_exit_pass();
102		return 0;
103	}
104
105	if (waitpid(pid, &status, 0) != pid)
106		return pr_perror("Unable to wait the child process");
107
108	if (WIFEXITED(status))
109		return WEXITSTATUS(status);
110
111	return 1;
112}
~/ Read-only file preview.