1// SPDX-License-Identifier: GPL-2.0-or-later
2/******************************************************************************
3 *
4 * Copyright FUJITSU LIMITED 2010
5 * Copyright KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
6 *
7 * DESCRIPTION
8 * Internally, Futex has two handling mode, anon and file. The private file
9 * mapping is special. At first it behave as file, but after write anything
10 * it behave as anon. This test is intent to test such case.
11 *
12 * AUTHOR
13 * KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
14 *
15 * HISTORY
16 * 2010-Jan-6: Initial version by KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
17 *
18 *****************************************************************************/
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <syscall.h>
23#include <unistd.h>
24#include <errno.h>
25#include <linux/futex.h>
26#include <pthread.h>
27#include <libgen.h>
28#include <signal.h>
29
30#include "logging.h"
31#include "futextest.h"
32
33#define TEST_NAME "futex-wait-private-mapped-file"
34#define PAGE_SZ 4096
35
36char pad[PAGE_SZ] = {1};
37futex_t val = 1;
38char pad2[PAGE_SZ] = {1};
39
40#define WAKE_WAIT_US 3000000
41struct timespec wait_timeout = { .tv_sec = 5, .tv_nsec = 0};
42
43void usage(char *prog)
44{
45 printf("Usage: %s\n", prog);
46 printf(" -c Use color\n");
47 printf(" -h Display this help message\n");
48 printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",
49 VQUIET, VCRITICAL, VINFO);
50}
51
52void *thr_futex_wait(void *arg)
53{
54 int ret;
55
56 info("futex wait\n");
57 ret = futex_wait(&val, 1, &wait_timeout, 0);
58 if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) {
59 error("futex error.\n", errno);
60 print_result(TEST_NAME, RET_ERROR);
61 exit(RET_ERROR);
62 }
63
64 if (ret && errno == ETIMEDOUT)
65 fail("waiter timedout\n");
66
67 info("futex_wait: ret = %d, errno = %d\n", ret, errno);
68
69 return NULL;
70}
71
72int main(int argc, char **argv)
73{
74 pthread_t thr;
75 int ret = RET_PASS;
76 int res;
77 int c;
78
79 while ((c = getopt(argc, argv, "chv:")) != -1) {
80 switch (c) {
81 case 'c':
82 log_color(1);
83 break;
84 case 'h':
85 usage(prog: basename(argv[0]));
86 exit(0);
87 case 'v':
88 log_verbosity(atoi(optarg));
89 break;
90 default:
91 usage(prog: basename(argv[0]));
92 exit(1);
93 }
94 }
95
96 ksft_print_header();
97 ksft_set_plan(1);
98 ksft_print_msg(
99 "%s: Test the futex value of private file mappings in FUTEX_WAIT\n",
100 basename(argv[0]));
101
102 ret = pthread_create(&thr, NULL, thr_futex_wait, NULL);
103 if (ret < 0) {
104 fprintf(stderr, "pthread_create error\n");
105 ret = RET_ERROR;
106 goto out;
107 }
108
109 info("wait a while\n");
110 usleep(WAKE_WAIT_US);
111 val = 2;
112 res = futex_wake(&val, 1, 0);
113 info("futex_wake %d\n", res);
114 if (res != 1) {
115 fail("FUTEX_WAKE didn't find the waiting thread.\n");
116 ret = RET_FAIL;
117 }
118
119 info("join\n");
120 pthread_join(thr, NULL);
121
122 out:
123 print_result(TEST_NAME, ret);
124 return ret;
125}
126

source code of linux/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c