xref: /aosp_15_r20/external/igt-gpu-tools/tests/sw_sync.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 Collabora, Ltd.
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  * Authors:
24*d83cc019SAndroid Build Coastguard Worker  *    Robert Foss <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  */
26*d83cc019SAndroid Build Coastguard Worker 
27*d83cc019SAndroid Build Coastguard Worker #include <pthread.h>
28*d83cc019SAndroid Build Coastguard Worker #include <semaphore.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdatomic.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/socket.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
33*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
34*d83cc019SAndroid Build Coastguard Worker 
35*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
36*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
37*d83cc019SAndroid Build Coastguard Worker #include "igt_primes.h"
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker #include "sw_sync.h"
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker 
42*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test SW Sync Framework");
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker typedef struct {
45*d83cc019SAndroid Build Coastguard Worker 	int timeline;
46*d83cc019SAndroid Build Coastguard Worker 	uint32_t thread_id;
47*d83cc019SAndroid Build Coastguard Worker 	_Atomic(uint32_t) *counter;
48*d83cc019SAndroid Build Coastguard Worker 	sem_t *sem;
49*d83cc019SAndroid Build Coastguard Worker } data_t;
50*d83cc019SAndroid Build Coastguard Worker 
test_alloc_timeline(void)51*d83cc019SAndroid Build Coastguard Worker static void test_alloc_timeline(void)
52*d83cc019SAndroid Build Coastguard Worker {
53*d83cc019SAndroid Build Coastguard Worker 	int timeline;
54*d83cc019SAndroid Build Coastguard Worker 
55*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
56*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
57*d83cc019SAndroid Build Coastguard Worker }
58*d83cc019SAndroid Build Coastguard Worker 
test_alloc_fence(void)59*d83cc019SAndroid Build Coastguard Worker static void test_alloc_fence(void)
60*d83cc019SAndroid Build Coastguard Worker {
61*d83cc019SAndroid Build Coastguard Worker 	int in_fence;
62*d83cc019SAndroid Build Coastguard Worker 	int timeline;
63*d83cc019SAndroid Build Coastguard Worker 
64*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
65*d83cc019SAndroid Build Coastguard Worker 	in_fence = sw_sync_timeline_create_fence(timeline, 0);
66*d83cc019SAndroid Build Coastguard Worker 
67*d83cc019SAndroid Build Coastguard Worker 	close(in_fence);
68*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
69*d83cc019SAndroid Build Coastguard Worker }
70*d83cc019SAndroid Build Coastguard Worker 
test_alloc_fence_invalid_timeline(void)71*d83cc019SAndroid Build Coastguard Worker static void test_alloc_fence_invalid_timeline(void)
72*d83cc019SAndroid Build Coastguard Worker {
73*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(__sw_sync_timeline_create_fence(-1, 0) < 0,
74*d83cc019SAndroid Build Coastguard Worker 	    "Did not fail to create fence on invalid timeline\n");
75*d83cc019SAndroid Build Coastguard Worker }
76*d83cc019SAndroid Build Coastguard Worker 
test_timeline_closed(void)77*d83cc019SAndroid Build Coastguard Worker static void test_timeline_closed(void)
78*d83cc019SAndroid Build Coastguard Worker {
79*d83cc019SAndroid Build Coastguard Worker 	int fence;
80*d83cc019SAndroid Build Coastguard Worker 	int timeline;
81*d83cc019SAndroid Build Coastguard Worker 
82*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
83*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(timeline, 1);
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
86*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == 0,
87*d83cc019SAndroid Build Coastguard Worker 		     "Failure waiting on unsignaled fence on closed timeline\n");
88*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_status(fence) == -ENOENT,
89*d83cc019SAndroid Build Coastguard Worker 		     "Failure in marking up an unsignaled fence on closed timeline\n");
90*d83cc019SAndroid Build Coastguard Worker }
91*d83cc019SAndroid Build Coastguard Worker 
test_timeline_closed_signaled(void)92*d83cc019SAndroid Build Coastguard Worker static void test_timeline_closed_signaled(void)
93*d83cc019SAndroid Build Coastguard Worker {
94*d83cc019SAndroid Build Coastguard Worker 	int fence;
95*d83cc019SAndroid Build Coastguard Worker 	int timeline;
96*d83cc019SAndroid Build Coastguard Worker 
97*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
98*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(timeline, 1);
99*d83cc019SAndroid Build Coastguard Worker 
100*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
101*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
102*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == 0,
103*d83cc019SAndroid Build Coastguard Worker 	             "Failure waiting on signaled fence for closed timeline\n");
104*d83cc019SAndroid Build Coastguard Worker }
105*d83cc019SAndroid Build Coastguard Worker 
test_alloc_merge_fence(void)106*d83cc019SAndroid Build Coastguard Worker static void test_alloc_merge_fence(void)
107*d83cc019SAndroid Build Coastguard Worker {
108*d83cc019SAndroid Build Coastguard Worker 	int in_fence[2];
109*d83cc019SAndroid Build Coastguard Worker 	int fence_merge;
110*d83cc019SAndroid Build Coastguard Worker 	int timeline[2];
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	timeline[0] = sw_sync_timeline_create();
113*d83cc019SAndroid Build Coastguard Worker 	timeline[1] = sw_sync_timeline_create();
114*d83cc019SAndroid Build Coastguard Worker 
115*d83cc019SAndroid Build Coastguard Worker 	in_fence[0] = sw_sync_timeline_create_fence(timeline[0], 1);
116*d83cc019SAndroid Build Coastguard Worker 	in_fence[1] = sw_sync_timeline_create_fence(timeline[1], 1);
117*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence[1], in_fence[0]);
118*d83cc019SAndroid Build Coastguard Worker 
119*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[0]);
120*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[1]);
121*d83cc019SAndroid Build Coastguard Worker 	close(fence_merge);
122*d83cc019SAndroid Build Coastguard Worker 	close(timeline[0]);
123*d83cc019SAndroid Build Coastguard Worker 	close(timeline[1]);
124*d83cc019SAndroid Build Coastguard Worker }
125*d83cc019SAndroid Build Coastguard Worker 
test_sync_busy(void)126*d83cc019SAndroid Build Coastguard Worker static void test_sync_busy(void)
127*d83cc019SAndroid Build Coastguard Worker {
128*d83cc019SAndroid Build Coastguard Worker 	int fence;
129*d83cc019SAndroid Build Coastguard Worker 	int timeline;
130*d83cc019SAndroid Build Coastguard Worker 	int seqno;
131*d83cc019SAndroid Build Coastguard Worker 
132*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
133*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(timeline, 5);
134*d83cc019SAndroid Build Coastguard Worker 
135*d83cc019SAndroid Build Coastguard Worker 	/* Make sure that fence has not been signaled yet */
136*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == -ETIME,
137*d83cc019SAndroid Build Coastguard Worker 		     "Fence signaled early (timeline value 0, fence seqno 5)\n");
138*d83cc019SAndroid Build Coastguard Worker 
139*d83cc019SAndroid Build Coastguard Worker 	/* Advance timeline from 0 -> 1 */
140*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	/* Make sure that fence has not been signaled yet */
143*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == -ETIME,
144*d83cc019SAndroid Build Coastguard Worker 		     "Fence signaled early (timeline value 1, fence seqno 5)\n");
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 	/* Advance timeline from 1 -> 5: signaling the fence (seqno 5)*/
147*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 4);
148*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == 0,
149*d83cc019SAndroid Build Coastguard Worker 		     "Fence not signaled (timeline value 5, fence seqno 5)\n");
150*d83cc019SAndroid Build Coastguard Worker 
151*d83cc019SAndroid Build Coastguard Worker 	/* Go even further, and confirm wait still succeeds */
152*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 5);
153*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == 0,
154*d83cc019SAndroid Build Coastguard Worker 		     "Fence not signaled (timeline value 10, fence seqno 5)\n");
155*d83cc019SAndroid Build Coastguard Worker 
156*d83cc019SAndroid Build Coastguard Worker 	seqno = 10;
157*d83cc019SAndroid Build Coastguard Worker 	for_each_prime_number(prime, 100) {
158*d83cc019SAndroid Build Coastguard Worker 		int fence_prime;
159*d83cc019SAndroid Build Coastguard Worker 		seqno += prime;
160*d83cc019SAndroid Build Coastguard Worker 
161*d83cc019SAndroid Build Coastguard Worker 		fence_prime = sw_sync_timeline_create_fence(timeline, seqno);
162*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(timeline, prime);
163*d83cc019SAndroid Build Coastguard Worker 
164*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(sync_fence_wait(fence_prime, 0) == 0,
165*d83cc019SAndroid Build Coastguard Worker 			     "Fence not signaled during test of prime timeline increments\n");
166*d83cc019SAndroid Build Coastguard Worker 		close(fence_prime);
167*d83cc019SAndroid Build Coastguard Worker 	}
168*d83cc019SAndroid Build Coastguard Worker 
169*d83cc019SAndroid Build Coastguard Worker 	close(fence);
170*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
171*d83cc019SAndroid Build Coastguard Worker }
172*d83cc019SAndroid Build Coastguard Worker 
test_sync_busy_fork_unixsocket(void)173*d83cc019SAndroid Build Coastguard Worker static void test_sync_busy_fork_unixsocket(void)
174*d83cc019SAndroid Build Coastguard Worker {
175*d83cc019SAndroid Build Coastguard Worker 	int fence;
176*d83cc019SAndroid Build Coastguard Worker 	int timeline;
177*d83cc019SAndroid Build Coastguard Worker 	int sv[2];
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker 	igt_require(socketpair(AF_UNIX, SOCK_DGRAM, 0, sv) == 0);
180*d83cc019SAndroid Build Coastguard Worker 
181*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
182*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(timeline, 1);
183*d83cc019SAndroid Build Coastguard Worker 
184*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
185*d83cc019SAndroid Build Coastguard Worker 		/* Child process */
186*d83cc019SAndroid Build Coastguard Worker 		int socket = sv[1];
187*d83cc019SAndroid Build Coastguard Worker 		int socket_timeline;
188*d83cc019SAndroid Build Coastguard Worker 		struct msghdr msg = {0};
189*d83cc019SAndroid Build Coastguard Worker 		struct cmsghdr *cmsg;
190*d83cc019SAndroid Build Coastguard Worker 		unsigned char *data;
191*d83cc019SAndroid Build Coastguard Worker 		char m_buffer[256];
192*d83cc019SAndroid Build Coastguard Worker 		char c_buffer[256];
193*d83cc019SAndroid Build Coastguard Worker 		struct iovec io = { .iov_base = m_buffer, .iov_len = sizeof(m_buffer) };
194*d83cc019SAndroid Build Coastguard Worker 		close(sv[0]);
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 		msg.msg_iov = &io;
197*d83cc019SAndroid Build Coastguard Worker 		msg.msg_iovlen = 1;
198*d83cc019SAndroid Build Coastguard Worker 		msg.msg_control = c_buffer;
199*d83cc019SAndroid Build Coastguard Worker 		msg.msg_controllen = sizeof(c_buffer);
200*d83cc019SAndroid Build Coastguard Worker 
201*d83cc019SAndroid Build Coastguard Worker 		igt_assert(recvmsg(socket, &msg, 0) > 0);
202*d83cc019SAndroid Build Coastguard Worker 
203*d83cc019SAndroid Build Coastguard Worker 		cmsg = CMSG_FIRSTHDR(&msg);
204*d83cc019SAndroid Build Coastguard Worker 		data = CMSG_DATA(cmsg);
205*d83cc019SAndroid Build Coastguard Worker 		socket_timeline = *((int *) data);
206*d83cc019SAndroid Build Coastguard Worker 
207*d83cc019SAndroid Build Coastguard Worker 		/* Advance timeline from 0 -> 1 */
208*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(socket_timeline, 1);
209*d83cc019SAndroid Build Coastguard Worker 	}
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	{
212*d83cc019SAndroid Build Coastguard Worker 		/* Parent process */
213*d83cc019SAndroid Build Coastguard Worker 		int socket = sv[0];
214*d83cc019SAndroid Build Coastguard Worker 		struct cmsghdr *cmsg;
215*d83cc019SAndroid Build Coastguard Worker 		struct iovec io = { .iov_base = (char *)"ABC", .iov_len = 3 };
216*d83cc019SAndroid Build Coastguard Worker 		struct msghdr msg = { 0 };
217*d83cc019SAndroid Build Coastguard Worker 		char buf[CMSG_SPACE(sizeof(timeline))];
218*d83cc019SAndroid Build Coastguard Worker 		memset(buf, '\0', sizeof(buf));
219*d83cc019SAndroid Build Coastguard Worker 		close(sv[1]);
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 		msg.msg_iov = &io;
222*d83cc019SAndroid Build Coastguard Worker 		msg.msg_iovlen = 1;
223*d83cc019SAndroid Build Coastguard Worker 		msg.msg_control = buf;
224*d83cc019SAndroid Build Coastguard Worker 		msg.msg_controllen = sizeof(buf);
225*d83cc019SAndroid Build Coastguard Worker 
226*d83cc019SAndroid Build Coastguard Worker 		cmsg = CMSG_FIRSTHDR(&msg);
227*d83cc019SAndroid Build Coastguard Worker 		cmsg->cmsg_level = SOL_SOCKET;
228*d83cc019SAndroid Build Coastguard Worker 		cmsg->cmsg_type = SCM_RIGHTS;
229*d83cc019SAndroid Build Coastguard Worker 		cmsg->cmsg_len = CMSG_LEN(sizeof(timeline));
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker 		*((int *) CMSG_DATA(cmsg)) = timeline;
232*d83cc019SAndroid Build Coastguard Worker 		msg.msg_controllen = cmsg->cmsg_len;
233*d83cc019SAndroid Build Coastguard Worker 
234*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(sync_fence_wait(fence, 0) == -ETIME,
235*d83cc019SAndroid Build Coastguard Worker 			     "Fence signaled (it should not have been signalled yet)\n");
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 		igt_assert(sendmsg(socket, &msg, 0) > 0);
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(sync_fence_wait(fence, 2*1000) == 0,
240*d83cc019SAndroid Build Coastguard Worker 			     "Fence not signaled (timeline value 1 fence seqno 1)\n");
241*d83cc019SAndroid Build Coastguard Worker 	}
242*d83cc019SAndroid Build Coastguard Worker 
243*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	close(fence);
246*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
247*d83cc019SAndroid Build Coastguard Worker }
248*d83cc019SAndroid Build Coastguard Worker 
test_sync_busy_fork(void)249*d83cc019SAndroid Build Coastguard Worker static void test_sync_busy_fork(void)
250*d83cc019SAndroid Build Coastguard Worker {
251*d83cc019SAndroid Build Coastguard Worker 	int timeline = sw_sync_timeline_create();
252*d83cc019SAndroid Build Coastguard Worker 	int fence = sw_sync_timeline_create_fence(timeline, 1);
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 0) == -ETIME,
255*d83cc019SAndroid Build Coastguard Worker 		     "Fence signaled (it should not have been signalled yet)\n");
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
258*d83cc019SAndroid Build Coastguard Worker 		usleep(1*1000*1000);
259*d83cc019SAndroid Build Coastguard Worker 		/* Advance timeline from 0 -> 1 */
260*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(timeline, 1);
261*d83cc019SAndroid Build Coastguard Worker 	}
262*d83cc019SAndroid Build Coastguard Worker 
263*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 2*1000) == 0,
264*d83cc019SAndroid Build Coastguard Worker 		     "Fence not signaled (timeline value 1 fence seqno 1)\n");
265*d83cc019SAndroid Build Coastguard Worker 
266*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
267*d83cc019SAndroid Build Coastguard Worker 
268*d83cc019SAndroid Build Coastguard Worker 	close(fence);
269*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
270*d83cc019SAndroid Build Coastguard Worker }
271*d83cc019SAndroid Build Coastguard Worker 
test_sync_merge_invalid(void)272*d83cc019SAndroid Build Coastguard Worker static void test_sync_merge_invalid(void)
273*d83cc019SAndroid Build Coastguard Worker {
274*d83cc019SAndroid Build Coastguard Worker 	int in_fence;
275*d83cc019SAndroid Build Coastguard Worker 	int fence_invalid;
276*d83cc019SAndroid Build Coastguard Worker 	int fence_merge;
277*d83cc019SAndroid Build Coastguard Worker 	int timeline;
278*d83cc019SAndroid Build Coastguard Worker 	char tmppath[] = "/tmp/igt-XXXXXX";
279*d83cc019SAndroid Build Coastguard Worker 	int skip = 0;
280*d83cc019SAndroid Build Coastguard Worker 
281*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
282*d83cc019SAndroid Build Coastguard Worker 	in_fence = sw_sync_timeline_create_fence(timeline, 1);
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	fence_invalid = -1;
285*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence, fence_invalid);
286*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(fence_merge < 0, "Verify invalid fd (-1) handling");
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 	fence_invalid = drm_open_driver(DRIVER_ANY);
289*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence, fence_invalid);
290*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(fence_merge < 0, "Verify invalid fd (device fd) handling");
291*d83cc019SAndroid Build Coastguard Worker 
292*d83cc019SAndroid Build Coastguard Worker 	fence_invalid = mkstemp(tmppath);
293*d83cc019SAndroid Build Coastguard Worker 	if (fence_invalid == -1) {
294*d83cc019SAndroid Build Coastguard Worker 		skip = 1;
295*d83cc019SAndroid Build Coastguard Worker 		goto out;
296*d83cc019SAndroid Build Coastguard Worker 	}
297*d83cc019SAndroid Build Coastguard Worker 	unlink(tmppath);
298*d83cc019SAndroid Build Coastguard Worker 	fence_invalid = drm_open_driver(DRIVER_ANY);
299*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence, fence_invalid);
300*d83cc019SAndroid Build Coastguard Worker 	close(fence_invalid);
301*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(fence_merge < 0, "Verify invalid fd (file fd) handling");
302*d83cc019SAndroid Build Coastguard Worker 
303*d83cc019SAndroid Build Coastguard Worker out:
304*d83cc019SAndroid Build Coastguard Worker 	close(in_fence);
305*d83cc019SAndroid Build Coastguard Worker 	close(fence_merge);
306*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
307*d83cc019SAndroid Build Coastguard Worker 	igt_require(skip == 0);
308*d83cc019SAndroid Build Coastguard Worker }
309*d83cc019SAndroid Build Coastguard Worker 
test_sync_merge(void)310*d83cc019SAndroid Build Coastguard Worker static void test_sync_merge(void)
311*d83cc019SAndroid Build Coastguard Worker {
312*d83cc019SAndroid Build Coastguard Worker 	int in_fence[3];
313*d83cc019SAndroid Build Coastguard Worker 	int fence_merge;
314*d83cc019SAndroid Build Coastguard Worker 	int timeline;
315*d83cc019SAndroid Build Coastguard Worker 	int active, signaled;
316*d83cc019SAndroid Build Coastguard Worker 
317*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
318*d83cc019SAndroid Build Coastguard Worker 	in_fence[0] = sw_sync_timeline_create_fence(timeline, 1);
319*d83cc019SAndroid Build Coastguard Worker 	in_fence[1] = sw_sync_timeline_create_fence(timeline, 2);
320*d83cc019SAndroid Build Coastguard Worker 	in_fence[2] = sw_sync_timeline_create_fence(timeline, 3);
321*d83cc019SAndroid Build Coastguard Worker 
322*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence[0], in_fence[1]);
323*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence[2], fence_merge);
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 	/* confirm all fences have one active point (even d) */
326*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(in_fence[0],
327*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
328*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1, "in_fence[0] has too many active fences\n");
329*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(in_fence[1],
330*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
331*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1, "in_fence[1] has too many active fences\n");
332*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(in_fence[2],
333*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
334*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1, "in_fence[2] has too many active fences\n");
335*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
336*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
337*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1, "fence_merge has too many active fences\n");
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker 	/* confirm that fence_merge is not signaled until the max of fence 0,1,2 */
340*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
341*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(in_fence[0],
342*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
343*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
344*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
345*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(signaled == 1, "in_fence[0] did not signal\n");
346*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1, "fence_merge signaled too early\n");
347*d83cc019SAndroid Build Coastguard Worker 
348*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
349*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(in_fence[1],
350*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
351*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
352*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
353*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(signaled == 1, "in_fence[1] did not signal\n");
354*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1, "fence_merge signaled too early\n");
355*d83cc019SAndroid Build Coastguard Worker 
356*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
357*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(in_fence[2],
358*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
359*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(signaled == 1, "in_fence[2] did not signal\n");
360*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(fence_merge,
361*d83cc019SAndroid Build Coastguard Worker 					       SW_SYNC_FENCE_STATUS_SIGNALED);
362*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
363*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
364*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 0 && signaled == 1,
365*d83cc019SAndroid Build Coastguard Worker 		     "fence_merge did not signal\n");
366*d83cc019SAndroid Build Coastguard Worker 
367*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[0]);
368*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[1]);
369*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[2]);
370*d83cc019SAndroid Build Coastguard Worker 	close(fence_merge);
371*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
372*d83cc019SAndroid Build Coastguard Worker }
373*d83cc019SAndroid Build Coastguard Worker 
test_sync_merge_same(void)374*d83cc019SAndroid Build Coastguard Worker static void test_sync_merge_same(void)
375*d83cc019SAndroid Build Coastguard Worker {
376*d83cc019SAndroid Build Coastguard Worker 	int in_fence[2];
377*d83cc019SAndroid Build Coastguard Worker 	int timeline;
378*d83cc019SAndroid Build Coastguard Worker 	int signaled;
379*d83cc019SAndroid Build Coastguard Worker 
380*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
381*d83cc019SAndroid Build Coastguard Worker 	in_fence[0] = sw_sync_timeline_create_fence(timeline, 1);
382*d83cc019SAndroid Build Coastguard Worker 	in_fence[1] = sync_fence_merge(in_fence[0], in_fence[0]);
383*d83cc019SAndroid Build Coastguard Worker 
384*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(in_fence[0],
385*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
386*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(signaled == 0, "Fence signaled too early\n");
387*d83cc019SAndroid Build Coastguard Worker 
388*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
389*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(in_fence[0],
390*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
391*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(signaled == 1, "Fence did not signal\n");
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[0]);
394*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[1]);
395*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
396*d83cc019SAndroid Build Coastguard Worker }
397*d83cc019SAndroid Build Coastguard Worker 
test_sync_multi_timeline_wait(void)398*d83cc019SAndroid Build Coastguard Worker static void test_sync_multi_timeline_wait(void)
399*d83cc019SAndroid Build Coastguard Worker {
400*d83cc019SAndroid Build Coastguard Worker 	int timeline[3];
401*d83cc019SAndroid Build Coastguard Worker 	int in_fence[3];
402*d83cc019SAndroid Build Coastguard Worker 	int fence_merge;
403*d83cc019SAndroid Build Coastguard Worker 	int active, signaled;
404*d83cc019SAndroid Build Coastguard Worker 
405*d83cc019SAndroid Build Coastguard Worker 	timeline[0] = sw_sync_timeline_create();
406*d83cc019SAndroid Build Coastguard Worker 	timeline[1] = sw_sync_timeline_create();
407*d83cc019SAndroid Build Coastguard Worker 	timeline[2] = sw_sync_timeline_create();
408*d83cc019SAndroid Build Coastguard Worker 
409*d83cc019SAndroid Build Coastguard Worker 	in_fence[0] = sw_sync_timeline_create_fence(timeline[0], 5);
410*d83cc019SAndroid Build Coastguard Worker 	in_fence[1] = sw_sync_timeline_create_fence(timeline[1], 5);
411*d83cc019SAndroid Build Coastguard Worker 	in_fence[2] = sw_sync_timeline_create_fence(timeline[2], 5);
412*d83cc019SAndroid Build Coastguard Worker 
413*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence[0], in_fence[1]);
414*d83cc019SAndroid Build Coastguard Worker 	fence_merge = sync_fence_merge(in_fence[2], fence_merge);
415*d83cc019SAndroid Build Coastguard Worker 
416*d83cc019SAndroid Build Coastguard Worker 	/* Confirm fence isn't signaled */
417*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
418*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
419*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 3, "Fence signaled too early\n");
420*d83cc019SAndroid Build Coastguard Worker 
421*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence_merge, 0) == -ETIME,
422*d83cc019SAndroid Build Coastguard Worker 		     "Failure waiting on fence until timeout\n");
423*d83cc019SAndroid Build Coastguard Worker 
424*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline[0], 5);
425*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
426*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
427*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(fence_merge,
428*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
429*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 2 && signaled == 1,
430*d83cc019SAndroid Build Coastguard Worker 		    "Fence did not signal properly\n");
431*d83cc019SAndroid Build Coastguard Worker 
432*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline[1], 5);
433*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
434*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
435*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(fence_merge,
436*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
437*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 1 && signaled == 2,
438*d83cc019SAndroid Build Coastguard Worker 		    "Fence did not signal properly\n");
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline[2], 5);
441*d83cc019SAndroid Build Coastguard Worker 	active = sync_fence_count_status(fence_merge,
442*d83cc019SAndroid Build Coastguard Worker 					    SW_SYNC_FENCE_STATUS_ACTIVE);
443*d83cc019SAndroid Build Coastguard Worker 	signaled = sync_fence_count_status(fence_merge,
444*d83cc019SAndroid Build Coastguard Worker 					      SW_SYNC_FENCE_STATUS_SIGNALED);
445*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(active == 0 && signaled == 3,
446*d83cc019SAndroid Build Coastguard Worker 		     "Fence did not signal properly\n");
447*d83cc019SAndroid Build Coastguard Worker 
448*d83cc019SAndroid Build Coastguard Worker 	/* confirm you can successfully wait */
449*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence_merge, 100) == 0,
450*d83cc019SAndroid Build Coastguard Worker 		     "Failure waiting on signaled fence\n");
451*d83cc019SAndroid Build Coastguard Worker 
452*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[0]);
453*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[1]);
454*d83cc019SAndroid Build Coastguard Worker 	close(in_fence[2]);
455*d83cc019SAndroid Build Coastguard Worker 	close(fence_merge);
456*d83cc019SAndroid Build Coastguard Worker 	close(timeline[0]);
457*d83cc019SAndroid Build Coastguard Worker 	close(timeline[1]);
458*d83cc019SAndroid Build Coastguard Worker 	close(timeline[2]);
459*d83cc019SAndroid Build Coastguard Worker }
460*d83cc019SAndroid Build Coastguard Worker 
461*d83cc019SAndroid Build Coastguard Worker #define MULTI_CONSUMER_THREADS 8
462*d83cc019SAndroid Build Coastguard Worker #define MULTI_CONSUMER_ITERATIONS (1 << 14)
test_sync_multi_consumer_thread(void * arg)463*d83cc019SAndroid Build Coastguard Worker static void * test_sync_multi_consumer_thread(void *arg)
464*d83cc019SAndroid Build Coastguard Worker {
465*d83cc019SAndroid Build Coastguard Worker 	data_t *data = arg;
466*d83cc019SAndroid Build Coastguard Worker 	int thread_id = data->thread_id;
467*d83cc019SAndroid Build Coastguard Worker 	int timeline = data->timeline;
468*d83cc019SAndroid Build Coastguard Worker 	int i;
469*d83cc019SAndroid Build Coastguard Worker 
470*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_ITERATIONS; i++) {
471*d83cc019SAndroid Build Coastguard Worker 		int next_point = i * MULTI_CONSUMER_THREADS + thread_id;
472*d83cc019SAndroid Build Coastguard Worker 		int fence = sw_sync_timeline_create_fence(timeline, next_point);
473*d83cc019SAndroid Build Coastguard Worker 
474*d83cc019SAndroid Build Coastguard Worker 		if (sync_fence_wait(fence, 1000) < 0)
475*d83cc019SAndroid Build Coastguard Worker 			return (void *) 1;
476*d83cc019SAndroid Build Coastguard Worker 
477*d83cc019SAndroid Build Coastguard Worker 		if (READ_ONCE(*data->counter) != next_point)
478*d83cc019SAndroid Build Coastguard Worker 			return (void *) 1;
479*d83cc019SAndroid Build Coastguard Worker 
480*d83cc019SAndroid Build Coastguard Worker 		sem_post(data->sem);
481*d83cc019SAndroid Build Coastguard Worker 		close(fence);
482*d83cc019SAndroid Build Coastguard Worker 	}
483*d83cc019SAndroid Build Coastguard Worker 	return NULL;
484*d83cc019SAndroid Build Coastguard Worker }
485*d83cc019SAndroid Build Coastguard Worker 
test_sync_multi_consumer(void)486*d83cc019SAndroid Build Coastguard Worker static void test_sync_multi_consumer(void)
487*d83cc019SAndroid Build Coastguard Worker {
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker 	data_t data_arr[MULTI_CONSUMER_THREADS];
490*d83cc019SAndroid Build Coastguard Worker 	pthread_t thread_arr[MULTI_CONSUMER_THREADS];
491*d83cc019SAndroid Build Coastguard Worker 	sem_t sem;
492*d83cc019SAndroid Build Coastguard Worker 	int timeline;
493*d83cc019SAndroid Build Coastguard Worker 	_Atomic(uint32_t) counter = 0;
494*d83cc019SAndroid Build Coastguard Worker 	uintptr_t thread_ret = 0;
495*d83cc019SAndroid Build Coastguard Worker 	data_t data;
496*d83cc019SAndroid Build Coastguard Worker 	int i, ret;
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker 	sem_init(&sem, 0, 0);
499*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
500*d83cc019SAndroid Build Coastguard Worker 
501*d83cc019SAndroid Build Coastguard Worker 	data.counter = &counter;
502*d83cc019SAndroid Build Coastguard Worker 	data.timeline = timeline;
503*d83cc019SAndroid Build Coastguard Worker 	data.sem = &sem;
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker 	/* Start sync threads. */
506*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_THREADS; i++)
507*d83cc019SAndroid Build Coastguard Worker 	{
508*d83cc019SAndroid Build Coastguard Worker 		data_arr[i] = data;
509*d83cc019SAndroid Build Coastguard Worker 		data_arr[i].thread_id = i;
510*d83cc019SAndroid Build Coastguard Worker 		ret = pthread_create(&thread_arr[i], NULL,
511*d83cc019SAndroid Build Coastguard Worker 				     test_sync_multi_consumer_thread,
512*d83cc019SAndroid Build Coastguard Worker 				     (void *) &(data_arr[i]));
513*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 0);
514*d83cc019SAndroid Build Coastguard Worker 	}
515*d83cc019SAndroid Build Coastguard Worker 
516*d83cc019SAndroid Build Coastguard Worker 	/* Produce 'content'. */
517*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_THREADS * MULTI_CONSUMER_ITERATIONS; i++)
518*d83cc019SAndroid Build Coastguard Worker 	{
519*d83cc019SAndroid Build Coastguard Worker 		sem_wait(&sem);
520*d83cc019SAndroid Build Coastguard Worker 
521*d83cc019SAndroid Build Coastguard Worker 		atomic_fetch_add(&counter, 1);
522*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(timeline, 1);
523*d83cc019SAndroid Build Coastguard Worker 	}
524*d83cc019SAndroid Build Coastguard Worker 
525*d83cc019SAndroid Build Coastguard Worker 	/* Wait for threads to complete. */
526*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_THREADS; i++)
527*d83cc019SAndroid Build Coastguard Worker 	{
528*d83cc019SAndroid Build Coastguard Worker 		uintptr_t local_thread_ret;
529*d83cc019SAndroid Build Coastguard Worker 		pthread_join(thread_arr[i], (void **)&local_thread_ret);
530*d83cc019SAndroid Build Coastguard Worker 		thread_ret |= local_thread_ret;
531*d83cc019SAndroid Build Coastguard Worker 	}
532*d83cc019SAndroid Build Coastguard Worker 
533*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
534*d83cc019SAndroid Build Coastguard Worker 	sem_destroy(&sem);
535*d83cc019SAndroid Build Coastguard Worker 
536*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(counter,
537*d83cc019SAndroid Build Coastguard Worker 		      MULTI_CONSUMER_THREADS * MULTI_CONSUMER_ITERATIONS);
538*d83cc019SAndroid Build Coastguard Worker 
539*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(thread_ret == 0, "A sync thread reported failure.\n");
540*d83cc019SAndroid Build Coastguard Worker }
541*d83cc019SAndroid Build Coastguard Worker 
542*d83cc019SAndroid Build Coastguard Worker #define MULTI_CONSUMER_PRODUCER_THREADS 8
543*d83cc019SAndroid Build Coastguard Worker #define MULTI_CONSUMER_PRODUCER_ITERATIONS (1 << 14)
test_sync_multi_consumer_producer_thread(void * arg)544*d83cc019SAndroid Build Coastguard Worker static void * test_sync_multi_consumer_producer_thread(void *arg)
545*d83cc019SAndroid Build Coastguard Worker {
546*d83cc019SAndroid Build Coastguard Worker 	data_t *data = arg;
547*d83cc019SAndroid Build Coastguard Worker 	int thread_id = data->thread_id;
548*d83cc019SAndroid Build Coastguard Worker 	int timeline = data->timeline;
549*d83cc019SAndroid Build Coastguard Worker 	int i;
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_PRODUCER_ITERATIONS; i++) {
552*d83cc019SAndroid Build Coastguard Worker 		int next_point = i * MULTI_CONSUMER_PRODUCER_THREADS + thread_id;
553*d83cc019SAndroid Build Coastguard Worker 		int fence = sw_sync_timeline_create_fence(timeline, next_point);
554*d83cc019SAndroid Build Coastguard Worker 
555*d83cc019SAndroid Build Coastguard Worker 		if (sync_fence_wait(fence, 1000) < 0)
556*d83cc019SAndroid Build Coastguard Worker 			return (void *) 1;
557*d83cc019SAndroid Build Coastguard Worker 
558*d83cc019SAndroid Build Coastguard Worker 		if (atomic_fetch_add(data->counter, 1) != next_point)
559*d83cc019SAndroid Build Coastguard Worker 			return (void *) 1;
560*d83cc019SAndroid Build Coastguard Worker 
561*d83cc019SAndroid Build Coastguard Worker 		/* Kick off the next thread. */
562*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(timeline, 1);
563*d83cc019SAndroid Build Coastguard Worker 
564*d83cc019SAndroid Build Coastguard Worker 		close(fence);
565*d83cc019SAndroid Build Coastguard Worker 	}
566*d83cc019SAndroid Build Coastguard Worker 	return NULL;
567*d83cc019SAndroid Build Coastguard Worker }
568*d83cc019SAndroid Build Coastguard Worker 
test_sync_multi_consumer_producer(void)569*d83cc019SAndroid Build Coastguard Worker static void test_sync_multi_consumer_producer(void)
570*d83cc019SAndroid Build Coastguard Worker {
571*d83cc019SAndroid Build Coastguard Worker 	data_t data_arr[MULTI_CONSUMER_PRODUCER_THREADS];
572*d83cc019SAndroid Build Coastguard Worker 	pthread_t thread_arr[MULTI_CONSUMER_PRODUCER_THREADS];
573*d83cc019SAndroid Build Coastguard Worker 	int timeline;
574*d83cc019SAndroid Build Coastguard Worker 	_Atomic(uint32_t) counter = 0;
575*d83cc019SAndroid Build Coastguard Worker 	uintptr_t thread_ret = 0;
576*d83cc019SAndroid Build Coastguard Worker 	data_t data;
577*d83cc019SAndroid Build Coastguard Worker 	int i, ret;
578*d83cc019SAndroid Build Coastguard Worker 
579*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
580*d83cc019SAndroid Build Coastguard Worker 
581*d83cc019SAndroid Build Coastguard Worker 	data.counter = &counter;
582*d83cc019SAndroid Build Coastguard Worker 	data.timeline = timeline;
583*d83cc019SAndroid Build Coastguard Worker 
584*d83cc019SAndroid Build Coastguard Worker 	/* Start consumer threads. */
585*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_PRODUCER_THREADS; i++)
586*d83cc019SAndroid Build Coastguard Worker 	{
587*d83cc019SAndroid Build Coastguard Worker 		data_arr[i] = data;
588*d83cc019SAndroid Build Coastguard Worker 		data_arr[i].thread_id = i;
589*d83cc019SAndroid Build Coastguard Worker 		ret = pthread_create(&thread_arr[i], NULL,
590*d83cc019SAndroid Build Coastguard Worker 				     test_sync_multi_consumer_producer_thread,
591*d83cc019SAndroid Build Coastguard Worker 				     (void *) &(data_arr[i]));
592*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 0);
593*d83cc019SAndroid Build Coastguard Worker 	}
594*d83cc019SAndroid Build Coastguard Worker 
595*d83cc019SAndroid Build Coastguard Worker 	/* Wait for threads to complete. */
596*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MULTI_CONSUMER_PRODUCER_THREADS; i++)
597*d83cc019SAndroid Build Coastguard Worker 	{
598*d83cc019SAndroid Build Coastguard Worker 		uintptr_t local_thread_ret;
599*d83cc019SAndroid Build Coastguard Worker 		pthread_join(thread_arr[i], (void **)&local_thread_ret);
600*d83cc019SAndroid Build Coastguard Worker 		thread_ret |= local_thread_ret;
601*d83cc019SAndroid Build Coastguard Worker 	}
602*d83cc019SAndroid Build Coastguard Worker 
603*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
604*d83cc019SAndroid Build Coastguard Worker 
605*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(counter,
606*d83cc019SAndroid Build Coastguard Worker 		      MULTI_CONSUMER_PRODUCER_THREADS *
607*d83cc019SAndroid Build Coastguard Worker 		      MULTI_CONSUMER_PRODUCER_ITERATIONS);
608*d83cc019SAndroid Build Coastguard Worker 
609*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(thread_ret == 0, "A sync thread reported failure.\n");
610*d83cc019SAndroid Build Coastguard Worker }
611*d83cc019SAndroid Build Coastguard Worker 
test_mspc_wait_on_fence(int fence)612*d83cc019SAndroid Build Coastguard Worker static int test_mspc_wait_on_fence(int fence)
613*d83cc019SAndroid Build Coastguard Worker {
614*d83cc019SAndroid Build Coastguard Worker 	int error, active;
615*d83cc019SAndroid Build Coastguard Worker 
616*d83cc019SAndroid Build Coastguard Worker 	do {
617*d83cc019SAndroid Build Coastguard Worker 		error = sync_fence_count_status(fence,
618*d83cc019SAndroid Build Coastguard Worker 						   SW_SYNC_FENCE_STATUS_ERROR);
619*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(error == 0, "Error occurred on fence\n");
620*d83cc019SAndroid Build Coastguard Worker 		active = sync_fence_count_status(fence,
621*d83cc019SAndroid Build Coastguard Worker 						    SW_SYNC_FENCE_STATUS_ACTIVE);
622*d83cc019SAndroid Build Coastguard Worker 	} while (active);
623*d83cc019SAndroid Build Coastguard Worker 
624*d83cc019SAndroid Build Coastguard Worker 	return 0;
625*d83cc019SAndroid Build Coastguard Worker }
626*d83cc019SAndroid Build Coastguard Worker 
627*d83cc019SAndroid Build Coastguard Worker static struct {
628*d83cc019SAndroid Build Coastguard Worker 	int iterations;
629*d83cc019SAndroid Build Coastguard Worker 	int threads;
630*d83cc019SAndroid Build Coastguard Worker 	int counter;
631*d83cc019SAndroid Build Coastguard Worker 	int cons_timeline;
632*d83cc019SAndroid Build Coastguard Worker 	int *prod_timeline;
633*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_t lock;
634*d83cc019SAndroid Build Coastguard Worker } test_mpsc_data;
635*d83cc019SAndroid Build Coastguard Worker 
mpsc_producer_thread(void * d)636*d83cc019SAndroid Build Coastguard Worker static void *mpsc_producer_thread(void *d)
637*d83cc019SAndroid Build Coastguard Worker {
638*d83cc019SAndroid Build Coastguard Worker 	int id = (long)d;
639*d83cc019SAndroid Build Coastguard Worker 	int fence, i;
640*d83cc019SAndroid Build Coastguard Worker 	int *prod_timeline = test_mpsc_data.prod_timeline;
641*d83cc019SAndroid Build Coastguard Worker 	int cons_timeline = test_mpsc_data.cons_timeline;
642*d83cc019SAndroid Build Coastguard Worker 	int iterations = test_mpsc_data.iterations;
643*d83cc019SAndroid Build Coastguard Worker 
644*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < iterations; i++) {
645*d83cc019SAndroid Build Coastguard Worker 		fence = sw_sync_timeline_create_fence(cons_timeline, i);
646*d83cc019SAndroid Build Coastguard Worker 
647*d83cc019SAndroid Build Coastguard Worker 		/* Wait for the consumer to finish. Use alternate
648*d83cc019SAndroid Build Coastguard Worker 		 * means of waiting on the fence
649*d83cc019SAndroid Build Coastguard Worker 		 */
650*d83cc019SAndroid Build Coastguard Worker 		if ((iterations + id) % 8 != 0) {
651*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(sync_fence_wait(fence, -1) == 0,
652*d83cc019SAndroid Build Coastguard Worker 				     "Failure waiting on fence\n");
653*d83cc019SAndroid Build Coastguard Worker 		} else {
654*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(test_mspc_wait_on_fence(fence) == 0,
655*d83cc019SAndroid Build Coastguard Worker 				     "Failure waiting on fence\n");
656*d83cc019SAndroid Build Coastguard Worker 		}
657*d83cc019SAndroid Build Coastguard Worker 
658*d83cc019SAndroid Build Coastguard Worker 		/* Every producer increments the counter, the consumer
659*d83cc019SAndroid Build Coastguard Worker 		 * checks and erases it
660*d83cc019SAndroid Build Coastguard Worker 		 */
661*d83cc019SAndroid Build Coastguard Worker 		pthread_mutex_lock(&test_mpsc_data.lock);
662*d83cc019SAndroid Build Coastguard Worker 		test_mpsc_data.counter++;
663*d83cc019SAndroid Build Coastguard Worker 		pthread_mutex_unlock(&test_mpsc_data.lock);
664*d83cc019SAndroid Build Coastguard Worker 
665*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(prod_timeline[id], 1);
666*d83cc019SAndroid Build Coastguard Worker 		close(fence);
667*d83cc019SAndroid Build Coastguard Worker 	}
668*d83cc019SAndroid Build Coastguard Worker 
669*d83cc019SAndroid Build Coastguard Worker 	return NULL;
670*d83cc019SAndroid Build Coastguard Worker }
671*d83cc019SAndroid Build Coastguard Worker 
mpsc_consumer_thread(void)672*d83cc019SAndroid Build Coastguard Worker static int mpsc_consumer_thread(void)
673*d83cc019SAndroid Build Coastguard Worker {
674*d83cc019SAndroid Build Coastguard Worker 	int fence, merged, tmp, it, i;
675*d83cc019SAndroid Build Coastguard Worker 	int *prod_timeline = test_mpsc_data.prod_timeline;
676*d83cc019SAndroid Build Coastguard Worker 	int cons_timeline = test_mpsc_data.cons_timeline;
677*d83cc019SAndroid Build Coastguard Worker 	int iterations = test_mpsc_data.iterations;
678*d83cc019SAndroid Build Coastguard Worker 	int n = test_mpsc_data.threads;
679*d83cc019SAndroid Build Coastguard Worker 
680*d83cc019SAndroid Build Coastguard Worker 	for (it = 1; it <= iterations; it++) {
681*d83cc019SAndroid Build Coastguard Worker 		fence = sw_sync_timeline_create_fence(prod_timeline[0], it);
682*d83cc019SAndroid Build Coastguard Worker 		for (i = 1; i < n; i++) {
683*d83cc019SAndroid Build Coastguard Worker 			tmp = sw_sync_timeline_create_fence(prod_timeline[i], it);
684*d83cc019SAndroid Build Coastguard Worker 			merged = sync_fence_merge(tmp, fence);
685*d83cc019SAndroid Build Coastguard Worker 			close(tmp);
686*d83cc019SAndroid Build Coastguard Worker 			close(fence);
687*d83cc019SAndroid Build Coastguard Worker 			fence = merged;
688*d83cc019SAndroid Build Coastguard Worker 		}
689*d83cc019SAndroid Build Coastguard Worker 
690*d83cc019SAndroid Build Coastguard Worker 		/* Make sure we see an increment from every producer thread.
691*d83cc019SAndroid Build Coastguard Worker 		 * Vary the means by which we wait.
692*d83cc019SAndroid Build Coastguard Worker 		 */
693*d83cc019SAndroid Build Coastguard Worker 		if (iterations % 8 != 0) {
694*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(sync_fence_wait(fence, -1) == 0,
695*d83cc019SAndroid Build Coastguard Worker 				    "Producers did not increment as expected\n");
696*d83cc019SAndroid Build Coastguard Worker 		} else {
697*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(test_mspc_wait_on_fence(fence) == 0,
698*d83cc019SAndroid Build Coastguard Worker 				     "Failure waiting on fence\n");
699*d83cc019SAndroid Build Coastguard Worker 		}
700*d83cc019SAndroid Build Coastguard Worker 
701*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(test_mpsc_data.counter == n * it,
702*d83cc019SAndroid Build Coastguard Worker 			     "Counter value mismatch\n");
703*d83cc019SAndroid Build Coastguard Worker 
704*d83cc019SAndroid Build Coastguard Worker 		/* Release the producer threads */
705*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(cons_timeline, 1);
706*d83cc019SAndroid Build Coastguard Worker 		close(fence);
707*d83cc019SAndroid Build Coastguard Worker 	}
708*d83cc019SAndroid Build Coastguard Worker 
709*d83cc019SAndroid Build Coastguard Worker 	return 0;
710*d83cc019SAndroid Build Coastguard Worker }
711*d83cc019SAndroid Build Coastguard Worker 
712*d83cc019SAndroid Build Coastguard Worker /* IMPORTANT NOTE: if you see this test failing on your system, it may be
713*d83cc019SAndroid Build Coastguard Worker  * due to a shortage of file descriptors. Please ensure your system has
714*d83cc019SAndroid Build Coastguard Worker  * a sensible limit for this test to finish correctly.
715*d83cc019SAndroid Build Coastguard Worker  */
test_sync_multi_producer_single_consumer(void)716*d83cc019SAndroid Build Coastguard Worker static void test_sync_multi_producer_single_consumer(void)
717*d83cc019SAndroid Build Coastguard Worker {
718*d83cc019SAndroid Build Coastguard Worker 	int iterations = 1 << 12;
719*d83cc019SAndroid Build Coastguard Worker 	int n = 5;
720*d83cc019SAndroid Build Coastguard Worker 	int prod_timeline[n];
721*d83cc019SAndroid Build Coastguard Worker 	int cons_timeline;
722*d83cc019SAndroid Build Coastguard Worker 	pthread_t threads[n];
723*d83cc019SAndroid Build Coastguard Worker 	long i;
724*d83cc019SAndroid Build Coastguard Worker 
725*d83cc019SAndroid Build Coastguard Worker 	cons_timeline = sw_sync_timeline_create();
726*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < n; i++)
727*d83cc019SAndroid Build Coastguard Worker 		prod_timeline[i] = sw_sync_timeline_create();
728*d83cc019SAndroid Build Coastguard Worker 
729*d83cc019SAndroid Build Coastguard Worker 	test_mpsc_data.prod_timeline = prod_timeline;
730*d83cc019SAndroid Build Coastguard Worker 	test_mpsc_data.cons_timeline = cons_timeline;
731*d83cc019SAndroid Build Coastguard Worker 	test_mpsc_data.iterations = iterations;
732*d83cc019SAndroid Build Coastguard Worker 	test_mpsc_data.threads = n;
733*d83cc019SAndroid Build Coastguard Worker 	test_mpsc_data.counter = 0;
734*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_init(&test_mpsc_data.lock, NULL);
735*d83cc019SAndroid Build Coastguard Worker 
736*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < n; i++) {
737*d83cc019SAndroid Build Coastguard Worker 		pthread_create(&threads[i], NULL, (void * (*)(void *))
738*d83cc019SAndroid Build Coastguard Worker 			       mpsc_producer_thread,
739*d83cc019SAndroid Build Coastguard Worker 			       (void *)i);
740*d83cc019SAndroid Build Coastguard Worker 	}
741*d83cc019SAndroid Build Coastguard Worker 
742*d83cc019SAndroid Build Coastguard Worker 	mpsc_consumer_thread();
743*d83cc019SAndroid Build Coastguard Worker 
744*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < n; i++)
745*d83cc019SAndroid Build Coastguard Worker 		pthread_join(threads[i], NULL);
746*d83cc019SAndroid Build Coastguard Worker }
747*d83cc019SAndroid Build Coastguard Worker 
test_sync_expired_merge(void)748*d83cc019SAndroid Build Coastguard Worker static void test_sync_expired_merge(void)
749*d83cc019SAndroid Build Coastguard Worker {
750*d83cc019SAndroid Build Coastguard Worker 	int iterations = 1 << 20;
751*d83cc019SAndroid Build Coastguard Worker 	int timeline;
752*d83cc019SAndroid Build Coastguard Worker 	int i;
753*d83cc019SAndroid Build Coastguard Worker 	int fence_expired, fence_merged;
754*d83cc019SAndroid Build Coastguard Worker 
755*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
756*d83cc019SAndroid Build Coastguard Worker 
757*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 100);
758*d83cc019SAndroid Build Coastguard Worker 	fence_expired = sw_sync_timeline_create_fence(timeline, 1);
759*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence_expired, 0) == 0,
760*d83cc019SAndroid Build Coastguard Worker 	             "Failure waiting for expired fence\n");
761*d83cc019SAndroid Build Coastguard Worker 
762*d83cc019SAndroid Build Coastguard Worker 	fence_merged = sync_fence_merge(fence_expired, fence_expired);
763*d83cc019SAndroid Build Coastguard Worker 	close(fence_merged);
764*d83cc019SAndroid Build Coastguard Worker 
765*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < iterations; i++) {
766*d83cc019SAndroid Build Coastguard Worker 		int fence = sync_fence_merge(fence_expired, fence_expired);
767*d83cc019SAndroid Build Coastguard Worker 
768*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(sync_fence_wait(fence, -1) == 0,
769*d83cc019SAndroid Build Coastguard Worker 			     "Failure waiting on fence\n");
770*d83cc019SAndroid Build Coastguard Worker 		close(fence);
771*d83cc019SAndroid Build Coastguard Worker 	}
772*d83cc019SAndroid Build Coastguard Worker 
773*d83cc019SAndroid Build Coastguard Worker 	close(fence_expired);
774*d83cc019SAndroid Build Coastguard Worker }
775*d83cc019SAndroid Build Coastguard Worker 
test_sync_random_merge(void)776*d83cc019SAndroid Build Coastguard Worker static void test_sync_random_merge(void)
777*d83cc019SAndroid Build Coastguard Worker {
778*d83cc019SAndroid Build Coastguard Worker 	int i, size;
779*d83cc019SAndroid Build Coastguard Worker 	const int nbr_timeline = 32;
780*d83cc019SAndroid Build Coastguard Worker 	const int nbr_merge = 1024;
781*d83cc019SAndroid Build Coastguard Worker 	int fence_map[nbr_timeline];
782*d83cc019SAndroid Build Coastguard Worker 	int timeline_arr[nbr_timeline];
783*d83cc019SAndroid Build Coastguard Worker 	int fence, tmpfence, merged;
784*d83cc019SAndroid Build Coastguard Worker 	int timeline, timeline_offset, sync_pt;
785*d83cc019SAndroid Build Coastguard Worker 
786*d83cc019SAndroid Build Coastguard Worker 	srand(time(NULL));
787*d83cc019SAndroid Build Coastguard Worker 
788*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < nbr_timeline; i++) {
789*d83cc019SAndroid Build Coastguard Worker 		timeline_arr[i] = sw_sync_timeline_create();
790*d83cc019SAndroid Build Coastguard Worker 		fence_map[i] = -1;
791*d83cc019SAndroid Build Coastguard Worker 	}
792*d83cc019SAndroid Build Coastguard Worker 
793*d83cc019SAndroid Build Coastguard Worker 	sync_pt = rand();
794*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(timeline_arr[0], sync_pt);
795*d83cc019SAndroid Build Coastguard Worker 
796*d83cc019SAndroid Build Coastguard Worker 	fence_map[0] = sync_pt;
797*d83cc019SAndroid Build Coastguard Worker 
798*d83cc019SAndroid Build Coastguard Worker 	/* Randomly create syncpoints out of a fixed set of timelines,
799*d83cc019SAndroid Build Coastguard Worker 	 * and merge them together.
800*d83cc019SAndroid Build Coastguard Worker 	 */
801*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < nbr_merge; i++) {
802*d83cc019SAndroid Build Coastguard Worker 		/* Generate syncpoint. */
803*d83cc019SAndroid Build Coastguard Worker 		timeline_offset = rand() % nbr_timeline;
804*d83cc019SAndroid Build Coastguard Worker 		timeline = timeline_arr[timeline_offset];
805*d83cc019SAndroid Build Coastguard Worker 		sync_pt = rand();
806*d83cc019SAndroid Build Coastguard Worker 
807*d83cc019SAndroid Build Coastguard Worker 		/* Keep track of the latest sync_pt in each timeline. */
808*d83cc019SAndroid Build Coastguard Worker 		if (fence_map[timeline_offset] == -1)
809*d83cc019SAndroid Build Coastguard Worker 			fence_map[timeline_offset] = sync_pt;
810*d83cc019SAndroid Build Coastguard Worker 		else if (fence_map[timeline_offset] < sync_pt)
811*d83cc019SAndroid Build Coastguard Worker 			fence_map[timeline_offset] = sync_pt;
812*d83cc019SAndroid Build Coastguard Worker 
813*d83cc019SAndroid Build Coastguard Worker 		/* Merge. */
814*d83cc019SAndroid Build Coastguard Worker 		tmpfence = sw_sync_timeline_create_fence(timeline, sync_pt);
815*d83cc019SAndroid Build Coastguard Worker 		merged = sync_fence_merge(tmpfence, fence);
816*d83cc019SAndroid Build Coastguard Worker 		close(tmpfence);
817*d83cc019SAndroid Build Coastguard Worker 		close(fence);
818*d83cc019SAndroid Build Coastguard Worker 		fence = merged;
819*d83cc019SAndroid Build Coastguard Worker 	}
820*d83cc019SAndroid Build Coastguard Worker 
821*d83cc019SAndroid Build Coastguard Worker 	size = 0;
822*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < nbr_timeline; i++)
823*d83cc019SAndroid Build Coastguard Worker 		if (fence_map[i] != -1)
824*d83cc019SAndroid Build Coastguard Worker 			size++;
825*d83cc019SAndroid Build Coastguard Worker 
826*d83cc019SAndroid Build Coastguard Worker 	/* Trigger the merged fence. */
827*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < nbr_timeline; i++) {
828*d83cc019SAndroid Build Coastguard Worker 		if (fence_map[i] != -1) {
829*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(sync_fence_wait(fence, 0) == -ETIME,
830*d83cc019SAndroid Build Coastguard Worker 				    "Failure waiting on fence until timeout\n");
831*d83cc019SAndroid Build Coastguard Worker 			/* Increment the timeline to the last sync_pt */
832*d83cc019SAndroid Build Coastguard Worker 			sw_sync_timeline_inc(timeline_arr[i], fence_map[i]);
833*d83cc019SAndroid Build Coastguard Worker 		}
834*d83cc019SAndroid Build Coastguard Worker 	}
835*d83cc019SAndroid Build Coastguard Worker 
836*d83cc019SAndroid Build Coastguard Worker 	/* Check that the fence is triggered. */
837*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(sync_fence_wait(fence, 1) == 0,
838*d83cc019SAndroid Build Coastguard Worker 		     "Failure triggering fence\n");
839*d83cc019SAndroid Build Coastguard Worker 
840*d83cc019SAndroid Build Coastguard Worker 	close(fence);
841*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < nbr_timeline; i++)
842*d83cc019SAndroid Build Coastguard Worker 		close(timeline_arr[i]);
843*d83cc019SAndroid Build Coastguard Worker }
844*d83cc019SAndroid Build Coastguard Worker 
845*d83cc019SAndroid Build Coastguard Worker igt_main
846*d83cc019SAndroid Build Coastguard Worker {
847*d83cc019SAndroid Build Coastguard Worker 	igt_fixture
848*d83cc019SAndroid Build Coastguard Worker 		igt_require_sw_sync();
849*d83cc019SAndroid Build Coastguard Worker 
850*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("alloc_timeline")
851*d83cc019SAndroid Build Coastguard Worker 		test_alloc_timeline();
852*d83cc019SAndroid Build Coastguard Worker 
853*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("alloc_fence")
854*d83cc019SAndroid Build Coastguard Worker 		test_alloc_fence();
855*d83cc019SAndroid Build Coastguard Worker 
856*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("alloc_fence_invalid_timeline")
857*d83cc019SAndroid Build Coastguard Worker 		test_alloc_fence_invalid_timeline();
858*d83cc019SAndroid Build Coastguard Worker 
859*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("timeline_closed")
860*d83cc019SAndroid Build Coastguard Worker 		test_timeline_closed();
861*d83cc019SAndroid Build Coastguard Worker 
862*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("timeline_closed_signaled")
863*d83cc019SAndroid Build Coastguard Worker 		test_timeline_closed_signaled();
864*d83cc019SAndroid Build Coastguard Worker 
865*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("alloc_merge_fence")
866*d83cc019SAndroid Build Coastguard Worker 		test_alloc_merge_fence();
867*d83cc019SAndroid Build Coastguard Worker 
868*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_busy")
869*d83cc019SAndroid Build Coastguard Worker 		test_sync_busy();
870*d83cc019SAndroid Build Coastguard Worker 
871*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_busy_fork")
872*d83cc019SAndroid Build Coastguard Worker 		test_sync_busy_fork();
873*d83cc019SAndroid Build Coastguard Worker 
874*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_busy_fork_unixsocket")
875*d83cc019SAndroid Build Coastguard Worker 		test_sync_busy_fork_unixsocket();
876*d83cc019SAndroid Build Coastguard Worker 
877*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_merge_invalid")
878*d83cc019SAndroid Build Coastguard Worker 		test_sync_merge_invalid();
879*d83cc019SAndroid Build Coastguard Worker 
880*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_merge")
881*d83cc019SAndroid Build Coastguard Worker 		test_sync_merge();
882*d83cc019SAndroid Build Coastguard Worker 
883*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_merge_same")
884*d83cc019SAndroid Build Coastguard Worker 		test_sync_merge_same();
885*d83cc019SAndroid Build Coastguard Worker 
886*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_multi_timeline_wait")
887*d83cc019SAndroid Build Coastguard Worker 		test_sync_multi_timeline_wait();
888*d83cc019SAndroid Build Coastguard Worker 
889*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_multi_consumer")
890*d83cc019SAndroid Build Coastguard Worker 		test_sync_multi_consumer();
891*d83cc019SAndroid Build Coastguard Worker 
892*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_multi_consumer_producer")
893*d83cc019SAndroid Build Coastguard Worker 		test_sync_multi_consumer_producer();
894*d83cc019SAndroid Build Coastguard Worker 
895*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_multi_producer_single_consumer")
896*d83cc019SAndroid Build Coastguard Worker 		test_sync_multi_producer_single_consumer();
897*d83cc019SAndroid Build Coastguard Worker 
898*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_expired_merge")
899*d83cc019SAndroid Build Coastguard Worker 		test_sync_expired_merge();
900*d83cc019SAndroid Build Coastguard Worker 
901*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sync_random_merge")
902*d83cc019SAndroid Build Coastguard Worker 		test_sync_random_merge();
903*d83cc019SAndroid Build Coastguard Worker }
904