xref: /aosp_15_r20/external/strace/tests-m32/futex.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2016 Eugene Syromyatnikov <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2016-2018 The strace developers.
4*cf84ac9aSAndroid Build Coastguard Worker  * All rights reserved.
5*cf84ac9aSAndroid Build Coastguard Worker  *
6*cf84ac9aSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
7*cf84ac9aSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
8*cf84ac9aSAndroid Build Coastguard Worker  * are met:
9*cf84ac9aSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
10*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
11*cf84ac9aSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
12*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
13*cf84ac9aSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
14*cf84ac9aSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
15*cf84ac9aSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
16*cf84ac9aSAndroid Build Coastguard Worker  *
17*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18*cf84ac9aSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19*cf84ac9aSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*cf84ac9aSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21*cf84ac9aSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22*cf84ac9aSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23*cf84ac9aSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24*cf84ac9aSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25*cf84ac9aSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*cf84ac9aSAndroid Build Coastguard Worker  */
28*cf84ac9aSAndroid Build Coastguard Worker 
29*cf84ac9aSAndroid Build Coastguard Worker #include "tests.h"
30*cf84ac9aSAndroid Build Coastguard Worker 
31*cf84ac9aSAndroid Build Coastguard Worker #include <asm/unistd.h>
32*cf84ac9aSAndroid Build Coastguard Worker 
33*cf84ac9aSAndroid Build Coastguard Worker #ifdef __NR_futex
34*cf84ac9aSAndroid Build Coastguard Worker 
35*cf84ac9aSAndroid Build Coastguard Worker # include <errno.h>
36*cf84ac9aSAndroid Build Coastguard Worker # include <stdarg.h>
37*cf84ac9aSAndroid Build Coastguard Worker # include <stdio.h>
38*cf84ac9aSAndroid Build Coastguard Worker # include <stdint.h>
39*cf84ac9aSAndroid Build Coastguard Worker # include <unistd.h>
40*cf84ac9aSAndroid Build Coastguard Worker 
41*cf84ac9aSAndroid Build Coastguard Worker # include <sys/time.h>
42*cf84ac9aSAndroid Build Coastguard Worker 
43*cf84ac9aSAndroid Build Coastguard Worker # ifndef FUTEX_PRIVATE_FLAG
44*cf84ac9aSAndroid Build Coastguard Worker #  define FUTEX_PRIVATE_FLAG 128
45*cf84ac9aSAndroid Build Coastguard Worker # endif
46*cf84ac9aSAndroid Build Coastguard Worker # ifndef FUTEX_CLOCK_REALTIME
47*cf84ac9aSAndroid Build Coastguard Worker #  define FUTEX_CLOCK_REALTIME 256
48*cf84ac9aSAndroid Build Coastguard Worker # endif
49*cf84ac9aSAndroid Build Coastguard Worker # ifndef FUTEX_CMD_MASK
50*cf84ac9aSAndroid Build Coastguard Worker #  define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
51*cf84ac9aSAndroid Build Coastguard Worker # endif
52*cf84ac9aSAndroid Build Coastguard Worker 
53*cf84ac9aSAndroid Build Coastguard Worker # include "xlat.h"
54*cf84ac9aSAndroid Build Coastguard Worker # include "xlat/futexops.h"
55*cf84ac9aSAndroid Build Coastguard Worker # include "xlat/futexwakeops.h"
56*cf84ac9aSAndroid Build Coastguard Worker # include "xlat/futexwakecmps.h"
57*cf84ac9aSAndroid Build Coastguard Worker 
futex_error(int * uaddr,int op,unsigned long val,unsigned long timeout,int * uaddr2,unsigned long val3,int rc,const char * func,int line)58*cf84ac9aSAndroid Build Coastguard Worker void futex_error(int *uaddr, int op, unsigned long val, unsigned long timeout,
59*cf84ac9aSAndroid Build Coastguard Worker 	int *uaddr2, unsigned long val3, int rc, const char *func, int line)
60*cf84ac9aSAndroid Build Coastguard Worker {
61*cf84ac9aSAndroid Build Coastguard Worker 	perror_msg_and_fail("%s:%d: futex(%p, %#x, %#x, %#lx, %p, %#x) = %d",
62*cf84ac9aSAndroid Build Coastguard Worker 		func, line, uaddr, op, (unsigned) val, timeout, uaddr,
63*cf84ac9aSAndroid Build Coastguard Worker 		(unsigned) val3, rc);
64*cf84ac9aSAndroid Build Coastguard Worker }
65*cf84ac9aSAndroid Build Coastguard Worker 
66*cf84ac9aSAndroid Build Coastguard Worker # define CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, \
67*cf84ac9aSAndroid Build Coastguard Worker 	enosys) \
68*cf84ac9aSAndroid Build Coastguard Worker 	do { \
69*cf84ac9aSAndroid Build Coastguard Worker 		errno = 0; \
70*cf84ac9aSAndroid Build Coastguard Worker 		rc = syscall(__NR_futex, (uaddr), (op), (val), (timeout), \
71*cf84ac9aSAndroid Build Coastguard Worker 			(uaddr2), (val3)); \
72*cf84ac9aSAndroid Build Coastguard Worker 		/* It is here due to EPERM on WAKE_OP on AArch64 */ \
73*cf84ac9aSAndroid Build Coastguard Worker 		if ((rc == -1) && (errno == EPERM)) \
74*cf84ac9aSAndroid Build Coastguard Worker 			break; \
75*cf84ac9aSAndroid Build Coastguard Worker 		if (enosys && (rc == -1) && (errno == ENOSYS)) \
76*cf84ac9aSAndroid Build Coastguard Worker 			break; \
77*cf84ac9aSAndroid Build Coastguard Worker 		if (!(check)) \
78*cf84ac9aSAndroid Build Coastguard Worker 			futex_error((uaddr), (op), (val), \
79*cf84ac9aSAndroid Build Coastguard Worker 				(unsigned long) (timeout), (int *) (uaddr2), \
80*cf84ac9aSAndroid Build Coastguard Worker 				(val3), rc, __func__, __LINE__); \
81*cf84ac9aSAndroid Build Coastguard Worker 	} while (0)
82*cf84ac9aSAndroid Build Coastguard Worker 
83*cf84ac9aSAndroid Build Coastguard Worker # define CHECK_FUTEX_ENOSYS(uaddr, op, val, timeout, uaddr2, val3, check) \
84*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, 1)
85*cf84ac9aSAndroid Build Coastguard Worker 
86*cf84ac9aSAndroid Build Coastguard Worker # define CHECK_FUTEX(uaddr, op, val, timeout, uaddr2, val3, check) \
87*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, 0)
88*cf84ac9aSAndroid Build Coastguard Worker 
89*cf84ac9aSAndroid Build Coastguard Worker enum argmask {
90*cf84ac9aSAndroid Build Coastguard Worker 	ARG3 = 1 << 0,
91*cf84ac9aSAndroid Build Coastguard Worker 	ARG4 = 1 << 1,
92*cf84ac9aSAndroid Build Coastguard Worker 	ARG5 = 1 << 2,
93*cf84ac9aSAndroid Build Coastguard Worker 	ARG6 = 1 << 3,
94*cf84ac9aSAndroid Build Coastguard Worker };
95*cf84ac9aSAndroid Build Coastguard Worker 
invalid_op(int * val,int op,uint32_t argmask,...)96*cf84ac9aSAndroid Build Coastguard Worker void invalid_op(int *val, int op, uint32_t argmask, ...)
97*cf84ac9aSAndroid Build Coastguard Worker {
98*cf84ac9aSAndroid Build Coastguard Worker 	static const unsigned long args[] = {
99*cf84ac9aSAndroid Build Coastguard Worker 		(unsigned long) 0xface1e55deadbee1ULL,
100*cf84ac9aSAndroid Build Coastguard Worker 		(unsigned long) 0xface1e56deadbee2ULL,
101*cf84ac9aSAndroid Build Coastguard Worker 		(unsigned long) 0xface1e57deadbee3ULL,
102*cf84ac9aSAndroid Build Coastguard Worker 		(unsigned long) 0xface1e58deadbee4ULL,
103*cf84ac9aSAndroid Build Coastguard Worker 	};
104*cf84ac9aSAndroid Build Coastguard Worker 	/* Since timeout value is copied before full op check, we should provide
105*cf84ac9aSAndroid Build Coastguard Worker 	 * some valid timeout address or NULL */
106*cf84ac9aSAndroid Build Coastguard Worker 	int cmd = op & FUTEX_CMD_MASK;
107*cf84ac9aSAndroid Build Coastguard Worker 	bool valid_timeout = (cmd == FUTEX_WAIT) || (cmd == FUTEX_LOCK_PI) ||
108*cf84ac9aSAndroid Build Coastguard Worker 		(cmd == FUTEX_WAIT_BITSET) || (cmd == FUTEX_WAIT_REQUEUE_PI);
109*cf84ac9aSAndroid Build Coastguard Worker 	bool timeout_is_val2 = (cmd == FUTEX_REQUEUE) ||
110*cf84ac9aSAndroid Build Coastguard Worker 		(cmd == FUTEX_CMP_REQUEUE) || (cmd == FUTEX_WAKE_OP) ||
111*cf84ac9aSAndroid Build Coastguard Worker 		(cmd == FUTEX_CMP_REQUEUE_PI);
112*cf84ac9aSAndroid Build Coastguard Worker 	const char *fmt;
113*cf84ac9aSAndroid Build Coastguard Worker 	int saved_errno;
114*cf84ac9aSAndroid Build Coastguard Worker 	int rc;
115*cf84ac9aSAndroid Build Coastguard Worker 	int i;
116*cf84ac9aSAndroid Build Coastguard Worker 	va_list ap;
117*cf84ac9aSAndroid Build Coastguard Worker 
118*cf84ac9aSAndroid Build Coastguard Worker 
119*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(val, op, args[0], valid_timeout ? 0 : args[1], args[2],
120*cf84ac9aSAndroid Build Coastguard Worker 		args[3], (rc == -1) && (errno == ENOSYS));
121*cf84ac9aSAndroid Build Coastguard Worker 	saved_errno = errno;
122*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, %#x /* FUTEX_??? */", val, op);
123*cf84ac9aSAndroid Build Coastguard Worker 
124*cf84ac9aSAndroid Build Coastguard Worker 	va_start(ap, argmask);
125*cf84ac9aSAndroid Build Coastguard Worker 
126*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < 4; i++) {
127*cf84ac9aSAndroid Build Coastguard Worker 		if (argmask & (1 << i)) {
128*cf84ac9aSAndroid Build Coastguard Worker 			fmt = va_arg(ap, const char *);
129*cf84ac9aSAndroid Build Coastguard Worker 
130*cf84ac9aSAndroid Build Coastguard Worker 			printf(", ");
131*cf84ac9aSAndroid Build Coastguard Worker 
132*cf84ac9aSAndroid Build Coastguard Worker 			if (((1 << i) == ARG3) || ((1 << i) == ARG6) ||
133*cf84ac9aSAndroid Build Coastguard Worker 			    (((1 << i) == ARG4) && timeout_is_val2))
134*cf84ac9aSAndroid Build Coastguard Worker 				printf(fmt, (unsigned) args[i]);
135*cf84ac9aSAndroid Build Coastguard Worker 			else
136*cf84ac9aSAndroid Build Coastguard Worker 				printf(fmt, args[i]);
137*cf84ac9aSAndroid Build Coastguard Worker 		}
138*cf84ac9aSAndroid Build Coastguard Worker 	}
139*cf84ac9aSAndroid Build Coastguard Worker 
140*cf84ac9aSAndroid Build Coastguard Worker 	va_end(ap);
141*cf84ac9aSAndroid Build Coastguard Worker 
142*cf84ac9aSAndroid Build Coastguard Worker 	errno = saved_errno;
143*cf84ac9aSAndroid Build Coastguard Worker 	printf(") = -1 ENOSYS (%m)\n");
144*cf84ac9aSAndroid Build Coastguard Worker }
145*cf84ac9aSAndroid Build Coastguard Worker 
146*cf84ac9aSAndroid Build Coastguard Worker # define CHECK_INVALID_CLOCKRT(op, ...) \
147*cf84ac9aSAndroid Build Coastguard Worker 	do { \
148*cf84ac9aSAndroid Build Coastguard Worker 		invalid_op(uaddr, FUTEX_CLOCK_REALTIME | (op), __VA_ARGS__); \
149*cf84ac9aSAndroid Build Coastguard Worker 		invalid_op(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG | \
150*cf84ac9aSAndroid Build Coastguard Worker 			(op), __VA_ARGS__); \
151*cf84ac9aSAndroid Build Coastguard Worker 	} while (0)
152*cf84ac9aSAndroid Build Coastguard Worker 
153*cf84ac9aSAndroid Build Coastguard Worker /* Value which differs from one stored in int *val */
154*cf84ac9aSAndroid Build Coastguard Worker # define VAL      ((unsigned long) 0xbadda7a0facefeedLLU)
155*cf84ac9aSAndroid Build Coastguard Worker # define VAL_PR   ((unsigned) VAL)
156*cf84ac9aSAndroid Build Coastguard Worker 
157*cf84ac9aSAndroid Build Coastguard Worker # define VALP     ((unsigned long) 0xbadda7a01acefeedLLU)
158*cf84ac9aSAndroid Build Coastguard Worker # define VALP_PR  ((unsigned) VALP)
159*cf84ac9aSAndroid Build Coastguard Worker 
160*cf84ac9aSAndroid Build Coastguard Worker # define VAL2     ((unsigned long) 0xbadda7a0ca7b100dLLU)
161*cf84ac9aSAndroid Build Coastguard Worker # define VAL2_PR  ((unsigned) VAL2)
162*cf84ac9aSAndroid Build Coastguard Worker 
163*cf84ac9aSAndroid Build Coastguard Worker # define VAL2P    ((unsigned long) 0xbadda7a07a7b100dLLU)
164*cf84ac9aSAndroid Build Coastguard Worker # define VAL2P_PR ((unsigned) VAL2P)
165*cf84ac9aSAndroid Build Coastguard Worker 
166*cf84ac9aSAndroid Build Coastguard Worker # define VAL3     ((unsigned long) 0xbadda7a09caffee1LLU)
167*cf84ac9aSAndroid Build Coastguard Worker # define VAL3_PR  ((unsigned) VAL3)
168*cf84ac9aSAndroid Build Coastguard Worker 
169*cf84ac9aSAndroid Build Coastguard Worker # define VAL3A    ((unsigned long) 0xbadda7a0ffffffffLLU)
170*cf84ac9aSAndroid Build Coastguard Worker # define VAL3A_PR "FUTEX_BITSET_MATCH_ANY"
171*cf84ac9aSAndroid Build Coastguard Worker 
172*cf84ac9aSAndroid Build Coastguard Worker int
main(int argc,char * argv[])173*cf84ac9aSAndroid Build Coastguard Worker main(int argc, char *argv[])
174*cf84ac9aSAndroid Build Coastguard Worker {
175*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(int, uaddr);
176*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(int, uaddr2);
177*cf84ac9aSAndroid Build Coastguard Worker 	int rc;
178*cf84ac9aSAndroid Build Coastguard Worker 	unsigned i;
179*cf84ac9aSAndroid Build Coastguard Worker 	unsigned j;
180*cf84ac9aSAndroid Build Coastguard Worker 
181*cf84ac9aSAndroid Build Coastguard Worker 	uaddr[0] = 0x1deadead;
182*cf84ac9aSAndroid Build Coastguard Worker 	uaddr2[0] = 0xbadf00d;
183*cf84ac9aSAndroid Build Coastguard Worker 
184*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, tmout);
185*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_sec = 123;
186*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_nsec = 0xbadc0de;
187*cf84ac9aSAndroid Build Coastguard Worker 
188*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_WAIT - check whether uaddr == val and sleep
189*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE, CLOCK_RT (since 4.5)
190*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
191*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_WAIT
192*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - expected value
193*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - address to timespec with timeout
194*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
195*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
196*cf84ac9aSAndroid Build Coastguard Worker 	 */
197*cf84ac9aSAndroid Build Coastguard Worker 
198*cf84ac9aSAndroid Build Coastguard Worker 	/* uaddr is NULL */
199*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(NULL, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
200*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EFAULT));
201*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(NULL, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
202*cf84ac9aSAndroid Build Coastguard Worker 	       VAL_PR, (long long) tmout->tv_sec,
203*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
204*cf84ac9aSAndroid Build Coastguard Worker 
205*cf84ac9aSAndroid Build Coastguard Worker 	/* uaddr is faulty */
206*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr + 1, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
207*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EFAULT));
208*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
209*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr + 1, VAL_PR, (long long) tmout->tv_sec,
210*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
211*cf84ac9aSAndroid Build Coastguard Worker 
212*cf84ac9aSAndroid Build Coastguard Worker 	/* timeout is faulty */
213*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout + 1, uaddr2, VAL3,
214*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EFAULT));
215*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT, %u, %p) = %s\n",
216*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, 0xfacefeed, tmout + 1, sprintrc(rc));
217*cf84ac9aSAndroid Build Coastguard Worker 
218*cf84ac9aSAndroid Build Coastguard Worker 	/* timeout is invalid */
219*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_sec = 0xdeadbeefU;
220*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_nsec = 0xfacefeedU;
221*cf84ac9aSAndroid Build Coastguard Worker 
222*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
223*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EINVAL));
224*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
225*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
226*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
227*cf84ac9aSAndroid Build Coastguard Worker 
228*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_sec = (time_t) 0xcafef00ddeadbeefLL;
229*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_nsec = (long) 0xbadc0dedfacefeedLL;
230*cf84ac9aSAndroid Build Coastguard Worker 
231*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
232*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EINVAL));
233*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
234*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
235*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
236*cf84ac9aSAndroid Build Coastguard Worker 
237*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_sec = 123;
238*cf84ac9aSAndroid Build Coastguard Worker 	tmout->tv_nsec = 0xbadc0de;
239*cf84ac9aSAndroid Build Coastguard Worker 
240*cf84ac9aSAndroid Build Coastguard Worker 	/* uaddr is not as provided; uaddr2 is faulty but ignored */
241*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2 + 1, VAL3,
242*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EAGAIN));
243*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
244*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
245*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
246*cf84ac9aSAndroid Build Coastguard Worker 
247*cf84ac9aSAndroid Build Coastguard Worker 	/* uaddr is not as provided; uaddr2 is faulty but ignored */
248*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT, VAL, tmout,
249*cf84ac9aSAndroid Build Coastguard Worker 		uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
250*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_PRIVATE, %u, {tv_sec=%lld, tv_nsec=%llu})"
251*cf84ac9aSAndroid Build Coastguard Worker 	       " = %s\n",
252*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
253*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
254*cf84ac9aSAndroid Build Coastguard Worker 
255*cf84ac9aSAndroid Build Coastguard Worker 	/* Next 2 tests are with CLOCKRT bit set */
256*cf84ac9aSAndroid Build Coastguard Worker 
257*cf84ac9aSAndroid Build Coastguard Worker 	/* Valid after v4.4-rc2-27-g337f130 */
258*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr,
259*cf84ac9aSAndroid Build Coastguard Worker 		FUTEX_CLOCK_REALTIME | FUTEX_WAIT,
260*cf84ac9aSAndroid Build Coastguard Worker 		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
261*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT|FUTEX_CLOCK_REALTIME, %u"
262*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
263*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
264*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
265*cf84ac9aSAndroid Build Coastguard Worker 
266*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr,
267*cf84ac9aSAndroid Build Coastguard Worker 		FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG | FUTEX_WAIT,
268*cf84ac9aSAndroid Build Coastguard Worker 		VAL, tmout, uaddr2, 0, (rc == -1) && (errno == EAGAIN));
269*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_PRIVATE|FUTEX_CLOCK_REALTIME, %u"
270*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
271*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
272*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
273*cf84ac9aSAndroid Build Coastguard Worker 
274*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_WAIT_BITSET - FUTEX_WAIT which provides additional bitmask
275*cf84ac9aSAndroid Build Coastguard Worker 	 *                     which should be matched at least in one bit with
276*cf84ac9aSAndroid Build Coastguard Worker 	 *                     wake mask in order to wake.
277*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE, CLOCKRT
278*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
279*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_TRYLOCK_PI
280*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - expected value stored in uaddr
281*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - timeout
282*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
283*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - bitmask
284*cf84ac9aSAndroid Build Coastguard Worker 	 */
285*cf84ac9aSAndroid Build Coastguard Worker 
286*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1,
287*cf84ac9aSAndroid Build Coastguard Worker 		VAL3, (rc == -1) && (errno == EAGAIN));
288*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {tv_sec=%lld, tv_nsec=%llu}"
289*cf84ac9aSAndroid Build Coastguard Worker 	       ", %#x) = %s\n",
290*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
291*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
292*cf84ac9aSAndroid Build Coastguard Worker 	       sprintrc(rc));
293*cf84ac9aSAndroid Build Coastguard Worker 
294*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1,
295*cf84ac9aSAndroid Build Coastguard Worker 		VAL3A, (rc == -1) && (errno == EAGAIN));
296*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {tv_sec=%lld, tv_nsec=%llu}"
297*cf84ac9aSAndroid Build Coastguard Worker 	       ", %s) = %s\n",
298*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
299*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3A_PR,
300*cf84ac9aSAndroid Build Coastguard Worker 	       sprintrc(rc));
301*cf84ac9aSAndroid Build Coastguard Worker 
302*cf84ac9aSAndroid Build Coastguard Worker 	/* val3 of 0 is invalid  */
303*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1, 0,
304*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EINVAL));
305*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {tv_sec=%lld, tv_nsec=%llu}"
306*cf84ac9aSAndroid Build Coastguard Worker 	       ", %#x) = %s\n",
307*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
308*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), 0, sprintrc(rc));
309*cf84ac9aSAndroid Build Coastguard Worker 
310*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT_BITSET, VAL,
311*cf84ac9aSAndroid Build Coastguard Worker 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
312*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET_PRIVATE, %u"
313*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
314*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
315*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
316*cf84ac9aSAndroid Build Coastguard Worker 	       sprintrc(rc));
317*cf84ac9aSAndroid Build Coastguard Worker 
318*cf84ac9aSAndroid Build Coastguard Worker 	/* Next 3 tests are with CLOCKRT bit set */
319*cf84ac9aSAndroid Build Coastguard Worker 
320*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_BITSET, VAL,
321*cf84ac9aSAndroid Build Coastguard Worker 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
322*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %u"
323*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
324*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
325*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
326*cf84ac9aSAndroid Build Coastguard Worker 	       sprintrc(rc));
327*cf84ac9aSAndroid Build Coastguard Worker 
328*cf84ac9aSAndroid Build Coastguard Worker 	/* val3 of 0 is invalid  */
329*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_BITSET, VAL,
330*cf84ac9aSAndroid Build Coastguard Worker 		tmout, uaddr2 + 1, 0, (rc == -1) && (errno == EINVAL));
331*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %u"
332*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
333*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
334*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), 0, sprintrc(rc));
335*cf84ac9aSAndroid Build Coastguard Worker 
336*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG |
337*cf84ac9aSAndroid Build Coastguard Worker 		FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1, VAL3,
338*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EAGAIN));
339*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, %u"
340*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
341*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
342*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
343*cf84ac9aSAndroid Build Coastguard Worker 	       sprintrc(rc));
344*cf84ac9aSAndroid Build Coastguard Worker 
345*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_WAKE - wake val processes waiting for uaddr
346*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
347*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
348*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_WAKE
349*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - how many processes to wake
350*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - not used
351*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
352*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
353*cf84ac9aSAndroid Build Coastguard Worker 	 */
354*cf84ac9aSAndroid Build Coastguard Worker 
355*cf84ac9aSAndroid Build Coastguard Worker 	/* Zero processes to wake is not a good idea, but it should return 0 */
356*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_WAKE, 0, NULL, NULL, 0, (rc == 0));
357*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE, %u) = %s\n", uaddr, 0, sprintrc(rc));
358*cf84ac9aSAndroid Build Coastguard Worker 
359*cf84ac9aSAndroid Build Coastguard Worker 	/* Trying to wake some processes, but there's nothing to wake */
360*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_WAKE, 10, NULL, NULL, 0, (rc == 0));
361*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE, %u) = %s\n", uaddr, 10, sprintrc(rc));
362*cf84ac9aSAndroid Build Coastguard Worker 
363*cf84ac9aSAndroid Build Coastguard Worker 	/* Trying to wake some processes, but there's nothing to wake */
364*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAKE, 10, NULL,
365*cf84ac9aSAndroid Build Coastguard Worker 		NULL, 0, (rc == 0));
366*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE_PRIVATE, %u) = %s\n", uaddr, 10,
367*cf84ac9aSAndroid Build Coastguard Worker 		sprintrc(rc));
368*cf84ac9aSAndroid Build Coastguard Worker 
369*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_WAKE, ARG3, "%u");
370*cf84ac9aSAndroid Build Coastguard Worker 
371*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_WAKE_BITSET - wake val processes waiting for uaddr which has at
372*cf84ac9aSAndroid Build Coastguard Worker 	 *                     least one common bit with bitset provided in
373*cf84ac9aSAndroid Build Coastguard Worker 	 *                     val3.
374*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
375*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
376*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_WAKE
377*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - how many processes to wake
378*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - not used
379*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
380*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - bitmask
381*cf84ac9aSAndroid Build Coastguard Worker 	 */
382*cf84ac9aSAndroid Build Coastguard Worker 
383*cf84ac9aSAndroid Build Coastguard Worker 	/* Trying to wake some processes, but there's nothing to wake */
384*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL,
385*cf84ac9aSAndroid Build Coastguard Worker 		VAL3, (rc == 0));
386*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %#x) = %s\n", uaddr, 10,
387*cf84ac9aSAndroid Build Coastguard Worker 		VAL3_PR, sprintrc(rc));
388*cf84ac9aSAndroid Build Coastguard Worker 
389*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL,
390*cf84ac9aSAndroid Build Coastguard Worker 		VAL3A, (rc == 0));
391*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %s) = %s\n", uaddr, 10,
392*cf84ac9aSAndroid Build Coastguard Worker 		VAL3A_PR, sprintrc(rc));
393*cf84ac9aSAndroid Build Coastguard Worker 
394*cf84ac9aSAndroid Build Coastguard Worker 	/* bitset 0 is invalid */
395*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL, 0,
396*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EINVAL));
397*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %#x) = %s\n", uaddr, 10, 0,
398*cf84ac9aSAndroid Build Coastguard Worker 		sprintrc(rc));
399*cf84ac9aSAndroid Build Coastguard Worker 
400*cf84ac9aSAndroid Build Coastguard Worker 	/* Trying to wake some processes, but there's nothing to wake */
401*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAKE_BITSET, 10,
402*cf84ac9aSAndroid Build Coastguard Worker 		NULL, NULL, VAL3, (rc == 0));
403*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAKE_BITSET_PRIVATE, %u, %#x) = %s\n", uaddr,
404*cf84ac9aSAndroid Build Coastguard Worker 		10, VAL3_PR, sprintrc(rc));
405*cf84ac9aSAndroid Build Coastguard Worker 
406*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_WAKE_BITSET, ARG3 | ARG6, "%u", "%#x");
407*cf84ac9aSAndroid Build Coastguard Worker 
408*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_FD - deprecated
409*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
410*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
411*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_FD
412*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - signal number
413*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - not used
414*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
415*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
416*cf84ac9aSAndroid Build Coastguard Worker 	 */
417*cf84ac9aSAndroid Build Coastguard Worker 
418*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_FD is not implemented since 2.6.26 */
419*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_FD, VAL, NULL, NULL, VAL3,
420*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EINVAL));
421*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_FD, %u) = %s\n", uaddr, VAL_PR, sprintrc(rc));
422*cf84ac9aSAndroid Build Coastguard Worker 
423*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_FD is not implemented since 2.6.26 */
424*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_FD, VAL, NULL,
425*cf84ac9aSAndroid Build Coastguard Worker 		NULL, VAL3, (rc == -1) && (errno == EINVAL));
426*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_FD|FUTEX_PRIVATE_FLAG, %u) = %s\n", uaddr,
427*cf84ac9aSAndroid Build Coastguard Worker 		VAL_PR, sprintrc(rc));
428*cf84ac9aSAndroid Build Coastguard Worker 
429*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_FD, ARG3, "%u");
430*cf84ac9aSAndroid Build Coastguard Worker 
431*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_REQUEUE - wake val processes and re-queue rest on uaddr2
432*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
433*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
434*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_REQUEUE
435*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - how many processes to wake
436*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. val2    - amount of processes to re-queue on uadr2
437*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - another futex address, to re-queue waiting processes on
438*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
439*cf84ac9aSAndroid Build Coastguard Worker 	 */
440*cf84ac9aSAndroid Build Coastguard Worker 
441*cf84ac9aSAndroid Build Coastguard Worker 	/* Trying to re-queue some processes but there's nothing to re-queue */
442*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_REQUEUE, VAL, VAL2, uaddr2, VAL3,
443*cf84ac9aSAndroid Build Coastguard Worker 		(rc == 0) || ((rc == -1) && (errno == EINVAL)));
444*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_REQUEUE, %u, %u, %p) = %s\n",
445*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, sprintrc(rc));
446*cf84ac9aSAndroid Build Coastguard Worker 
447*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_REQUEUE, VALP, VAL2P, uaddr2, VAL3,
448*cf84ac9aSAndroid Build Coastguard Worker 		(rc == 0));
449*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_REQUEUE, %u, %u, %p) = %s\n",
450*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VALP_PR, VAL2P_PR, uaddr2, sprintrc(rc));
451*cf84ac9aSAndroid Build Coastguard Worker 
452*cf84ac9aSAndroid Build Coastguard Worker 	/* Trying to re-queue some processes but there's nothing to re-queue */
453*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_REQUEUE, VAL, VAL2,
454*cf84ac9aSAndroid Build Coastguard Worker 		uaddr2, VAL3, (rc == 0) || ((rc == -1) && (errno == EINVAL)));
455*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_REQUEUE_PRIVATE, %u, %u, %p) = %s\n",
456*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, sprintrc(rc));
457*cf84ac9aSAndroid Build Coastguard Worker 
458*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_REQUEUE, VALP,
459*cf84ac9aSAndroid Build Coastguard Worker 		VAL2P, uaddr2, VAL3, (rc == 0));
460*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_REQUEUE_PRIVATE, %u, %u, %p) = %s\n",
461*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VALP_PR, VAL2P_PR, uaddr2, sprintrc(rc));
462*cf84ac9aSAndroid Build Coastguard Worker 
463*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_REQUEUE, ARG3 | ARG4 | ARG5, "%u", "%u",
464*cf84ac9aSAndroid Build Coastguard Worker 		"%#lx");
465*cf84ac9aSAndroid Build Coastguard Worker 
466*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_CMP_REQUEUE - wake val processes and re-queue rest on uaddr2
467*cf84ac9aSAndroid Build Coastguard Worker 	 *                     if uaddr has value val3
468*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
469*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
470*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_CMP_REQUEUE
471*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - how many processes to wake
472*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. val2    - amount of processes to re-queue on uadr2
473*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - another futex address, to re-queue waiting processes on
474*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - expected value stored in uaddr
475*cf84ac9aSAndroid Build Coastguard Worker 	 */
476*cf84ac9aSAndroid Build Coastguard Worker 
477*cf84ac9aSAndroid Build Coastguard Worker 	/* Comparison re-queue with wrong val value */
478*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VAL, VAL2, uaddr2, VAL3,
479*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EAGAIN || errno == EINVAL));
480*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
481*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, VAL3_PR, sprintrc(rc));
482*cf84ac9aSAndroid Build Coastguard Worker 
483*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VALP, VAL2P, uaddr2, VAL3,
484*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EAGAIN));
485*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
486*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VALP_PR, VAL2P_PR, uaddr2, VAL3_PR, sprintrc(rc));
487*cf84ac9aSAndroid Build Coastguard Worker 
488*cf84ac9aSAndroid Build Coastguard Worker 	/* Successful comparison re-queue */
489*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VAL, VAL2, uaddr2, *uaddr,
490*cf84ac9aSAndroid Build Coastguard Worker 		(rc == 0) || ((rc == -1) && (errno == EINVAL)));
491*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
492*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
493*cf84ac9aSAndroid Build Coastguard Worker 
494*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VALP, VAL2P, uaddr2, *uaddr,
495*cf84ac9aSAndroid Build Coastguard Worker 		(rc == 0));
496*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
497*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VALP_PR, VAL2P_PR, uaddr2, *uaddr, sprintrc(rc));
498*cf84ac9aSAndroid Build Coastguard Worker 
499*cf84ac9aSAndroid Build Coastguard Worker 	/* Successful comparison re-queue */
500*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE, VAL,
501*cf84ac9aSAndroid Build Coastguard Worker 		VAL2, uaddr2, *uaddr,
502*cf84ac9aSAndroid Build Coastguard Worker 		(rc == 0) || ((rc == -1) && (errno == EINVAL)));
503*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE_PRIVATE, %u, %u, %p, %u) = %s\n",
504*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
505*cf84ac9aSAndroid Build Coastguard Worker 
506*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE, VALP,
507*cf84ac9aSAndroid Build Coastguard Worker 		VAL2P, uaddr2, *uaddr, (rc == 0));
508*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE_PRIVATE, %u, %u, %p, %u) = %s\n",
509*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VALP_PR, VAL2P_PR, uaddr2, *uaddr, sprintrc(rc));
510*cf84ac9aSAndroid Build Coastguard Worker 
511*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_CMP_REQUEUE, ARG3 | ARG4 | ARG5 | ARG6,
512*cf84ac9aSAndroid Build Coastguard Worker 		"%u", "%u", "%#lx", "%u");
513*cf84ac9aSAndroid Build Coastguard Worker 
514*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_WAKE_OP - wake val processes waiting for uaddr, additionally
515*cf84ac9aSAndroid Build Coastguard Worker 	 *                 wake val2 processes waiting for uaddr2 in case
516*cf84ac9aSAndroid Build Coastguard Worker 	 *                 operation encoded in val3 (change of value at uaddr2
517*cf84ac9aSAndroid Build Coastguard Worker 	 *                 and comparison of previous value against provided
518*cf84ac9aSAndroid Build Coastguard Worker 	 *                 constant) succeedes with value at uaddr2. Operation
519*cf84ac9aSAndroid Build Coastguard Worker 	 *                 result is written to value of uaddr2 (in any case).
520*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
521*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_WAKE_OP
522*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - how many processes to wake
523*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. val2    - amount of processes to wake in case operation encoded in
524*cf84ac9aSAndroid Build Coastguard Worker 	 *              val3 returns true
525*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - another futex address, for conditional wake of
526*cf84ac9aSAndroid Build Coastguard Worker 	 *              additional processes
527*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - encoded operation:
528*cf84ac9aSAndroid Build Coastguard Worker 	 *                1. bit 31 - if 1 then value stored in field field 4
529*cf84ac9aSAndroid Build Coastguard Worker 	 *                            should be interpreted as power of 2.
530*cf84ac9aSAndroid Build Coastguard Worker 	 *                2. 28..30 - arithmetic operation which should be
531*cf84ac9aSAndroid Build Coastguard Worker 	 *                            applied to previous value stored in
532*cf84ac9aSAndroid Build Coastguard Worker 	 *                            uaddr2. Values available (from 2005 up to
533*cf84ac9aSAndroid Build Coastguard Worker 	 *                            2016): SET. ADD, OR, ANDN, XOR.
534*cf84ac9aSAndroid Build Coastguard Worker 	 *                3. 24..29 - comparison operation which should be
535*cf84ac9aSAndroid Build Coastguard Worker 	 *                            applied to the old value stored in uaddr2
536*cf84ac9aSAndroid Build Coastguard Worker 	 *                            (before arithmetic operation is applied).
537*cf84ac9aSAndroid Build Coastguard Worker 	 *                            Possible values: EQ, NE, LT, LE, GT, GE.
538*cf84ac9aSAndroid Build Coastguard Worker 	 *                4. 12..23 - Second operand for arithmetic operation.
539*cf84ac9aSAndroid Build Coastguard Worker 	 *                            If bit 31 is set, it is interpreted as
540*cf84ac9aSAndroid Build Coastguard Worker 	 *                            power of 2.
541*cf84ac9aSAndroid Build Coastguard Worker 	 *                5. 00..11 - Value against which old value stored in
542*cf84ac9aSAndroid Build Coastguard Worker 	 *                            uaddr2 is compared.
543*cf84ac9aSAndroid Build Coastguard Worker 	 */
544*cf84ac9aSAndroid Build Coastguard Worker 
545*cf84ac9aSAndroid Build Coastguard Worker 	static const struct {
546*cf84ac9aSAndroid Build Coastguard Worker 		uint32_t val;
547*cf84ac9aSAndroid Build Coastguard Worker 		const char *str;
548*cf84ac9aSAndroid Build Coastguard Worker 
549*cf84ac9aSAndroid Build Coastguard Worker 		/*
550*cf84ac9aSAndroid Build Coastguard Worker 		 * Peculiar semantics:
551*cf84ac9aSAndroid Build Coastguard Worker 		 *  * err == 0 and err2 != 0 => expect both either the absence
552*cf84ac9aSAndroid Build Coastguard Worker 		 *    of error or presence of err2
553*cf84ac9aSAndroid Build Coastguard Worker 		 *  * err != 0 and err2 == 0 => expect err only, no success
554*cf84ac9aSAndroid Build Coastguard Worker 		 *    expected.
555*cf84ac9aSAndroid Build Coastguard Worker 		 */
556*cf84ac9aSAndroid Build Coastguard Worker 		int err;
557*cf84ac9aSAndroid Build Coastguard Worker 		int err2;
558*cf84ac9aSAndroid Build Coastguard Worker 	} wake_ops[] = {
559*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x00000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
560*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x00fff000, "FUTEX_OP_SET<<28|0xfff<<12|FUTEX_OP_CMP_EQ<<24|"
561*cf84ac9aSAndroid Build Coastguard Worker 			"0" },
562*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x00000fff, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_EQ<<24|"
563*cf84ac9aSAndroid Build Coastguard Worker 			"0xfff" },
564*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x00ffffff, "FUTEX_OP_SET<<28|0xfff<<12|FUTEX_OP_CMP_EQ<<24|"
565*cf84ac9aSAndroid Build Coastguard Worker 			"0xfff" },
566*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x10000000, "FUTEX_OP_ADD<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
567*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x20000000, "FUTEX_OP_OR<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
568*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x30000000, "FUTEX_OP_ANDN<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
569*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x40000000, "FUTEX_OP_XOR<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
570*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x50000000, "0x5<<28 /* FUTEX_OP_??? */|0<<12|"
571*cf84ac9aSAndroid Build Coastguard Worker 			"FUTEX_OP_CMP_EQ<<24|0", ENOSYS },
572*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x70000000, "0x7<<28 /* FUTEX_OP_??? */|0<<12|"
573*cf84ac9aSAndroid Build Coastguard Worker 			"FUTEX_OP_CMP_EQ<<24|0", ENOSYS },
574*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x80000000, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_SET<<28|0<<12|"
575*cf84ac9aSAndroid Build Coastguard Worker 			"FUTEX_OP_CMP_EQ<<24|0" },
576*cf84ac9aSAndroid Build Coastguard Worker 		{ 0xa0caffee, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_OR<<28|"
577*cf84ac9aSAndroid Build Coastguard Worker 			"0xcaf<<12|FUTEX_OP_CMP_EQ<<24|0xfee", 0, EINVAL },
578*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x01000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_NE<<24|0" },
579*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x01234567, "FUTEX_OP_SET<<28|0x234<<12|FUTEX_OP_CMP_NE<<24|"
580*cf84ac9aSAndroid Build Coastguard Worker 			"0x567" },
581*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x02000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_LT<<24|0" },
582*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x03000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_LE<<24|0" },
583*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x04000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_GT<<24|0" },
584*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x05000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_GE<<24|0" },
585*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x06000000, "FUTEX_OP_SET<<28|0<<12|"
586*cf84ac9aSAndroid Build Coastguard Worker 			"0x6<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
587*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x07000000, "FUTEX_OP_SET<<28|0<<12|"
588*cf84ac9aSAndroid Build Coastguard Worker 			"0x7<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
589*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x08000000, "FUTEX_OP_SET<<28|0<<12|"
590*cf84ac9aSAndroid Build Coastguard Worker 			"0x8<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
591*cf84ac9aSAndroid Build Coastguard Worker 		{ 0x0f000000, "FUTEX_OP_SET<<28|0<<12|"
592*cf84ac9aSAndroid Build Coastguard Worker 			"0xf<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
593*cf84ac9aSAndroid Build Coastguard Worker 		{ 0xbadfaced, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_ANDN<<28|"
594*cf84ac9aSAndroid Build Coastguard Worker 			"0xdfa<<12|0xa<<24 /* FUTEX_OP_CMP_??? */|0xced",
595*cf84ac9aSAndroid Build Coastguard Worker 			ENOSYS, EINVAL },
596*cf84ac9aSAndroid Build Coastguard Worker 		{ 0xffffffff, "FUTEX_OP_OPARG_SHIFT<<28|"
597*cf84ac9aSAndroid Build Coastguard Worker 			"0x7<<28 /* FUTEX_OP_??? */|0xfff<<12|"
598*cf84ac9aSAndroid Build Coastguard Worker 			"0xf<<24 /* FUTEX_OP_CMP_??? */|0xfff",
599*cf84ac9aSAndroid Build Coastguard Worker 			ENOSYS, EINVAL },
600*cf84ac9aSAndroid Build Coastguard Worker 	};
601*cf84ac9aSAndroid Build Coastguard Worker 
602*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(wake_ops); i++) {
603*cf84ac9aSAndroid Build Coastguard Worker 		for (j = 0; j < 2; j++) {
604*cf84ac9aSAndroid Build Coastguard Worker 			CHECK_FUTEX_ENOSYS(uaddr,
605*cf84ac9aSAndroid Build Coastguard Worker 				j ? FUTEX_WAKE_OP_PRIVATE : FUTEX_WAKE_OP,
606*cf84ac9aSAndroid Build Coastguard Worker 				VAL, i, uaddr2, wake_ops[i].val,
607*cf84ac9aSAndroid Build Coastguard Worker 				/*
608*cf84ac9aSAndroid Build Coastguard Worker 				 * Either one of errs is 0 or rc == 0 is not
609*cf84ac9aSAndroid Build Coastguard Worker 				 * allowed.
610*cf84ac9aSAndroid Build Coastguard Worker 				 */
611*cf84ac9aSAndroid Build Coastguard Worker 				((!wake_ops[i].err || !wake_ops[i].err2 ||
612*cf84ac9aSAndroid Build Coastguard Worker 					(rc != 0)) &&
613*cf84ac9aSAndroid Build Coastguard Worker 				((!wake_ops[i].err && (rc == 0)) ||
614*cf84ac9aSAndroid Build Coastguard Worker 				(wake_ops[i].err  && (rc == -1) &&
615*cf84ac9aSAndroid Build Coastguard Worker 					(errno == wake_ops[i].err)) ||
616*cf84ac9aSAndroid Build Coastguard Worker 				(wake_ops[i].err2 && (rc == -1) &&
617*cf84ac9aSAndroid Build Coastguard Worker 					(errno == wake_ops[i].err2)))));
618*cf84ac9aSAndroid Build Coastguard Worker 			printf("futex(%p, FUTEX_WAKE_OP%s, %u, %u, %p, %s)"
619*cf84ac9aSAndroid Build Coastguard Worker 			       " = %s\n", uaddr, j ? "_PRIVATE" : "", VAL_PR,
620*cf84ac9aSAndroid Build Coastguard Worker 			       i, uaddr2, wake_ops[i].str, sprintrc(rc));
621*cf84ac9aSAndroid Build Coastguard Worker 		}
622*cf84ac9aSAndroid Build Coastguard Worker 	}
623*cf84ac9aSAndroid Build Coastguard Worker 
624*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_WAKE_OP, ARG3 | ARG4 | ARG5 | ARG6,
625*cf84ac9aSAndroid Build Coastguard Worker 		"%u", "%u", "%#lx",
626*cf84ac9aSAndroid Build Coastguard Worker 		/* Decoding of the 0xdeadbee4 value */
627*cf84ac9aSAndroid Build Coastguard Worker 		"FUTEX_OP_OPARG_SHIFT<<28|0x5<<28 /* FUTEX_OP_??? */|0xadb<<12|"
628*cf84ac9aSAndroid Build Coastguard Worker 		"0xe<<24 /* FUTEX_OP_CMP_??? */|0xee4");
629*cf84ac9aSAndroid Build Coastguard Worker 
630*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_LOCK_PI - slow path for mutex lock with process inheritance
631*cf84ac9aSAndroid Build Coastguard Worker 	 *                 support. Expect that futex has 0 in unlocked case and
632*cf84ac9aSAndroid Build Coastguard Worker 	 *                 TID of owning process in locked case. Value can also
633*cf84ac9aSAndroid Build Coastguard Worker 	 *                 contain FUTEX_WAITERS bit signalling the presence of
634*cf84ac9aSAndroid Build Coastguard Worker 	 *                 waiters queue.
635*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
636*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
637*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_LOCK_PI
638*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - not used
639*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - timeout
640*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
641*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
642*cf84ac9aSAndroid Build Coastguard Worker 	 */
643*cf84ac9aSAndroid Build Coastguard Worker 
644*cf84ac9aSAndroid Build Coastguard Worker 	*uaddr = getpid();
645*cf84ac9aSAndroid Build Coastguard Worker 
646*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_LOCK_PI, VAL, tmout, uaddr2 + 1,
647*cf84ac9aSAndroid Build Coastguard Worker 		VAL3, (rc == -1) && (errno == EFAULT));
648*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_LOCK_PI, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
649*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr + 1, (long long) tmout->tv_sec,
650*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
651*cf84ac9aSAndroid Build Coastguard Worker 
652*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_LOCK_PI, VAL,
653*cf84ac9aSAndroid Build Coastguard Worker 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
654*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_LOCK_PI_PRIVATE, {tv_sec=%lld, tv_nsec=%llu})"
655*cf84ac9aSAndroid Build Coastguard Worker 	       " = %s\n",
656*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr + 1, (long long) tmout->tv_sec,
657*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
658*cf84ac9aSAndroid Build Coastguard Worker 
659*cf84ac9aSAndroid Build Coastguard Worker 	/* NULL is passed by invalid_op() in cases valid timeout address is
660*cf84ac9aSAndroid Build Coastguard Worker 	 * needed */
661*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_LOCK_PI, ARG4, "NULL");
662*cf84ac9aSAndroid Build Coastguard Worker 
663*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_UNLOCK_PI - slow path for mutex unlock with process inheritance
664*cf84ac9aSAndroid Build Coastguard Worker 	 *                   support. Expected to be called by process in case
665*cf84ac9aSAndroid Build Coastguard Worker 	 *                   it failed to execute fast path (it usually means
666*cf84ac9aSAndroid Build Coastguard Worker 	 *                   that FUTEX_WAITERS flag had been set while the lock
667*cf84ac9aSAndroid Build Coastguard Worker 	 *                   has been held).
668*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
669*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
670*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_UNLOCK_PI
671*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - not used
672*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - not used
673*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
674*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
675*cf84ac9aSAndroid Build Coastguard Worker 	 */
676*cf84ac9aSAndroid Build Coastguard Worker 
677*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_UNLOCK_PI, VAL, tmout, uaddr2 + 1,
678*cf84ac9aSAndroid Build Coastguard Worker 		VAL3, (rc == -1) && (errno == EFAULT));
679*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_UNLOCK_PI) = %s\n", uaddr + 1, sprintrc(rc));
680*cf84ac9aSAndroid Build Coastguard Worker 
681*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_UNLOCK_PI, VAL,
682*cf84ac9aSAndroid Build Coastguard Worker 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
683*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_UNLOCK_PI_PRIVATE) = %s\n", uaddr + 1,
684*cf84ac9aSAndroid Build Coastguard Worker 		sprintrc(rc));
685*cf84ac9aSAndroid Build Coastguard Worker 
686*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_UNLOCK_PI, 0);
687*cf84ac9aSAndroid Build Coastguard Worker 
688*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_TRYLOCK_PI - slow path for mutex trylock with process
689*cf84ac9aSAndroid Build Coastguard Worker 	 *                 inheritance support.
690*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
691*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
692*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_TRYLOCK_PI
693*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - not used
694*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - not used
695*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - not used
696*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used
697*cf84ac9aSAndroid Build Coastguard Worker 	 */
698*cf84ac9aSAndroid Build Coastguard Worker 
699*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_TRYLOCK_PI, VAL, tmout, uaddr2 + 1,
700*cf84ac9aSAndroid Build Coastguard Worker 		VAL3, (rc == -1) && (errno == EFAULT));
701*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_TRYLOCK_PI) = %s\n", uaddr + 1, sprintrc(rc));
702*cf84ac9aSAndroid Build Coastguard Worker 
703*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_TRYLOCK_PI,
704*cf84ac9aSAndroid Build Coastguard Worker 		VAL, tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
705*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_TRYLOCK_PI_PRIVATE) = %s\n", uaddr + 1,
706*cf84ac9aSAndroid Build Coastguard Worker 		sprintrc(rc));
707*cf84ac9aSAndroid Build Coastguard Worker 
708*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_TRYLOCK_PI, 0);
709*cf84ac9aSAndroid Build Coastguard Worker 
710*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_WAIT_REQUEUE_PI - kernel-side handling of special case when
711*cf84ac9aSAndroid Build Coastguard Worker 	 *                         processes should be re-queued on PI-aware
712*cf84ac9aSAndroid Build Coastguard Worker 	 *                         futexes. This is so special since PI futexes
713*cf84ac9aSAndroid Build Coastguard Worker 	 *                         utilize rt_mutex and it should be at no time
714*cf84ac9aSAndroid Build Coastguard Worker 	 *                         left free with a wait queue, so this should
715*cf84ac9aSAndroid Build Coastguard Worker 	 *                         be performed atomically in-kernel.
716*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE, CLOCKRT
717*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
718*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_WAIT_REQUEUE_PI
719*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - expected value stored in uaddr
720*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. timeout - timeout
721*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - (PI-aware) futex address to requeue process on
722*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - not used (in kernel, it always initialized to
723*cf84ac9aSAndroid Build Coastguard Worker 	 *              FUTEX_BITSET_MATCH_ANY and passed to
724*cf84ac9aSAndroid Build Coastguard Worker 	 *              futex_wait_requeue_pi())
725*cf84ac9aSAndroid Build Coastguard Worker 	 */
726*cf84ac9aSAndroid Build Coastguard Worker 
727*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_REQUEUE_PI, VAL, tmout, uaddr2,
728*cf84ac9aSAndroid Build Coastguard Worker 		VAL3, (rc == -1) && (errno == EAGAIN));
729*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI, %u"
730*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
731*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
732*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
733*cf84ac9aSAndroid Build Coastguard Worker 
734*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT_REQUEUE_PI,
735*cf84ac9aSAndroid Build Coastguard Worker 		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
736*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI_PRIVATE, %u"
737*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
738*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
739*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
740*cf84ac9aSAndroid Build Coastguard Worker 
741*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_REQUEUE_PI,
742*cf84ac9aSAndroid Build Coastguard Worker 		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
743*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, %u"
744*cf84ac9aSAndroid Build Coastguard Worker 	       ", {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
745*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
746*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
747*cf84ac9aSAndroid Build Coastguard Worker 
748*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG |
749*cf84ac9aSAndroid Build Coastguard Worker 		FUTEX_WAIT_REQUEUE_PI, VAL, tmout, uaddr2, VAL3,
750*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EAGAIN));
751*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME"
752*cf84ac9aSAndroid Build Coastguard Worker 	       ", %u, {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
753*cf84ac9aSAndroid Build Coastguard Worker 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
754*cf84ac9aSAndroid Build Coastguard Worker 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
755*cf84ac9aSAndroid Build Coastguard Worker 
756*cf84ac9aSAndroid Build Coastguard Worker 	/* FUTEX_CMP_REQUEUE_PI - version of FUTEX_CMP_REQUEUE which re-queues
757*cf84ac9aSAndroid Build Coastguard Worker 	 *                        on PI-aware futex.
758*cf84ac9aSAndroid Build Coastguard Worker 	 * Possible flags: PRIVATE
759*cf84ac9aSAndroid Build Coastguard Worker 	 * 1. uaddr   - futex address
760*cf84ac9aSAndroid Build Coastguard Worker 	 * 2. op      - FUTEX_CMP_REQUEUE
761*cf84ac9aSAndroid Build Coastguard Worker 	 * 3. val     - how many processes to wake
762*cf84ac9aSAndroid Build Coastguard Worker 	 * 4. val2    - amount of processes to re-queue on uadr2
763*cf84ac9aSAndroid Build Coastguard Worker 	 * 5. uaddr2  - (PI-aware) futex address, to re-queue waiting processes
764*cf84ac9aSAndroid Build Coastguard Worker 	 *              on
765*cf84ac9aSAndroid Build Coastguard Worker 	 * 6. val3    - expected value stored in uaddr
766*cf84ac9aSAndroid Build Coastguard Worker 	 */
767*cf84ac9aSAndroid Build Coastguard Worker 
768*cf84ac9aSAndroid Build Coastguard Worker 	/* All these should fail with EINVAL since we try to re-queue to  non-PI
769*cf84ac9aSAndroid Build Coastguard Worker 	 * futex.
770*cf84ac9aSAndroid Build Coastguard Worker 	 */
771*cf84ac9aSAndroid Build Coastguard Worker 
772*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CMP_REQUEUE_PI, VAL, VAL2, uaddr2, VAL3,
773*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == EINVAL));
774*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE_PI, %u, %u, %p, %u) = %s\n",
775*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, VAL3_PR, sprintrc(rc));
776*cf84ac9aSAndroid Build Coastguard Worker 
777*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CMP_REQUEUE_PI, VAL, VAL2, uaddr2,
778*cf84ac9aSAndroid Build Coastguard Worker 		*uaddr, (rc == -1) && (errno == EINVAL));
779*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE_PI, %u, %u, %p, %u) = %s\n",
780*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
781*cf84ac9aSAndroid Build Coastguard Worker 
782*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE_PI,
783*cf84ac9aSAndroid Build Coastguard Worker 		VAL, VAL2, uaddr2, *uaddr, (rc == -1) && (errno == EINVAL));
784*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, FUTEX_CMP_REQUEUE_PI_PRIVATE, %u, %u, %p, %u) = %s\n",
785*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
786*cf84ac9aSAndroid Build Coastguard Worker 
787*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_INVALID_CLOCKRT(FUTEX_CMP_REQUEUE_PI, ARG3 | ARG4 | ARG5 | ARG6,
788*cf84ac9aSAndroid Build Coastguard Worker 		"%u", "%u", "%#lx", "%u");
789*cf84ac9aSAndroid Build Coastguard Worker 
790*cf84ac9aSAndroid Build Coastguard Worker 	/*
791*cf84ac9aSAndroid Build Coastguard Worker 	 * Unknown commands
792*cf84ac9aSAndroid Build Coastguard Worker 	 */
793*cf84ac9aSAndroid Build Coastguard Worker 
794*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, 0xd, VAL, tmout + 1, uaddr2 + 1, VAL3,
795*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == ENOSYS));
796*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, 0xd /* FUTEX_??? */, %u, %p, %p, %#x) = %s\n",
797*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, tmout + 1, uaddr2 + 1, VAL3_PR, sprintrc(rc));
798*cf84ac9aSAndroid Build Coastguard Worker 
799*cf84ac9aSAndroid Build Coastguard Worker 	CHECK_FUTEX(uaddr, 0xbefeeded, VAL, tmout + 1, uaddr2, VAL3,
800*cf84ac9aSAndroid Build Coastguard Worker 		(rc == -1) && (errno == ENOSYS));
801*cf84ac9aSAndroid Build Coastguard Worker 	printf("futex(%p, 0xbefeeded /* FUTEX_??? */, %u, %p, %p, %#x) = %s\n",
802*cf84ac9aSAndroid Build Coastguard Worker 		uaddr, VAL_PR, tmout + 1, uaddr2, VAL3_PR, sprintrc(rc));
803*cf84ac9aSAndroid Build Coastguard Worker 
804*cf84ac9aSAndroid Build Coastguard Worker 	puts("+++ exited with 0 +++");
805*cf84ac9aSAndroid Build Coastguard Worker 
806*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
807*cf84ac9aSAndroid Build Coastguard Worker }
808*cf84ac9aSAndroid Build Coastguard Worker 
809*cf84ac9aSAndroid Build Coastguard Worker #else
810*cf84ac9aSAndroid Build Coastguard Worker 
811*cf84ac9aSAndroid Build Coastguard Worker SKIP_MAIN_UNDEFINED("__NR_futex")
812*cf84ac9aSAndroid Build Coastguard Worker 
813*cf84ac9aSAndroid Build Coastguard Worker #endif
814