brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · 6b2b926 Raw
111 lines · c
1// SPDX-License-Identifier: GPL-2.02#define _GNU_SOURCE3#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 1000000000ULL19 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; // 100ms31	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	nscheck();70 71	ksft_set_plan(2);72 73	clock_gettime(CLOCK_MONOTONIC, &mtime_now);74 75	if (unshare_timens())76		return 1;77 78	len = snprintf(buf, sizeof(buf), "%d %d 0",79			CLOCK_MONOTONIC, 70 * 24 * 3600);80	fd = open("/proc/self/timens_offsets", O_WRONLY);81	if (fd < 0)82		return pr_perror("/proc/self/timens_offsets");83 84	if (write(fd, buf, len) != len)85		return pr_perror("/proc/self/timens_offsets");86 87	close(fd);88 89	pid = fork();90	if (pid < 0)91		return pr_perror("Unable to fork");92	if (pid == 0) {93		int ret = 0;94 95		ret |= run_test(CLOCK_REALTIME);96		ret |= run_test(CLOCK_MONOTONIC);97		if (ret)98			ksft_exit_fail();99		ksft_exit_pass();100		return 0;101	}102 103	if (waitpid(pid, &status, 0) != pid)104		return pr_perror("Unable to wait the child process");105 106	if (WIFEXITED(status))107		return WEXITSTATUS(status);108 109	return 1;110}111