blob: d9114ca8c4c8990e26a3ab9e65df462531c65602 [file] [log] [blame]
Jason Ekstrand1f09b852017-08-28 14:10:12 -07001/*
2 * Copyright © 2017 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include <errno.h>
25#include <xf86drm.h>
26
27#include "igt.h"
28#include "igt_syncobj.h"
29
30/**
31 * SECTION:igt_syncobj
32 * @short_description: Library with syncobj helpers
33 * @title: syncobj
34 * @include: igt_syncobj.h
35 *
36 * This library contains helpers for sync object tests.
37 */
38
39static int
40__syncobj_create(int fd, uint32_t *handle, uint32_t flags)
41{
42 struct drm_syncobj_create create = { 0 };
43 int err = 0;
44
45 create.flags = flags;
46 if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &create))
47 err = -errno;
48 *handle = create.handle;
49 return err;
50}
51
52/**
53 * syncobj_create
54 * @fd: The DRM file descriptor
55 * @flags: Flags to pass syncobj create
56 *
57 * Create a syncobj with the flags.
58 *
59 * Returns: A newly created syncobj
60 */
61uint32_t
62syncobj_create(int fd, uint32_t flags)
63{
64 uint32_t handle;
65 igt_assert_eq(__syncobj_create(fd, &handle, flags), 0);
66 igt_assert(handle);
67 return handle;
68}
69
70static int
71__syncobj_destroy(int fd, uint32_t handle)
72{
73 struct drm_syncobj_destroy destroy = { 0 };
74 int err = 0;
75
76 destroy.handle = handle;
77 if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &destroy))
78 err = -errno;
79 return err;
80}
81
82/**
83 * syncobj_destroy:
84 * @fd: The DRM file descriptor
85 * @handle: The handle to the syncobj to destroy
86 * Destroy a syncobj.
87 */
88void
89syncobj_destroy(int fd, uint32_t handle)
90{
91 igt_assert_eq(__syncobj_destroy(fd, handle), 0);
92}
93
94int
95__syncobj_handle_to_fd(int fd, struct drm_syncobj_handle *args)
96{
97 int err = 0;
98 if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, args))
99 err = -errno;
100 return err;
101}
102
103/**
104 * syncobj_handle_to_fd:
105 * @fd: The DRM file descriptor
106 * @handle: Handle to syncobj
107 * @flags: Flags to handle to fd ioctl.
108 *
109 * Convert a syncobj handle to an fd using the flags.
110 *
111 * Returns: a file descriptor (either syncobj or sync_file.
112 */
113int
114syncobj_handle_to_fd(int fd, uint32_t handle, uint32_t flags)
115{
116 struct drm_syncobj_handle args = { 0 };
117 args.handle = handle;
118 args.flags = flags;
119 igt_assert_eq(__syncobj_handle_to_fd(fd, &args), 0);
120 igt_assert(args.fd >= 0);
121 return args.fd;
122}
123
124int
125__syncobj_fd_to_handle(int fd, struct drm_syncobj_handle *args)
126{
127 int err = 0;
128 if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, args))
129 err = -errno;
130 return err;
131}
132
133/**
134 * syncobj_fd_to_handle:
135 * @fd: The DRM file descriptor
136 * @syncobj_fd: syncobj fd to convert
137 * @flags: Flags to the syncobj fd to handle ioctl.
138 *
139 * Convert a syncobj fd a syncobj handle using the flags.
140 *
141 * Returns: a syncobj handle.
142 */
143uint32_t
144syncobj_fd_to_handle(int fd, int syncobj_fd, uint32_t flags)
145{
146 struct drm_syncobj_handle args = { 0 };
147 args.fd = syncobj_fd;
148 args.flags = flags;
149 igt_assert_eq(__syncobj_fd_to_handle(fd, &args), 0);
150 igt_assert(args.handle > 0);
151 return args.handle;
152}
153
154/**
155 * syncobj_import_sync_file:
156 * @fd: The DRM file descriptor
157 * @handle: Handle to the syncobt to import file into
158 * @sync_file: The sync_file fd to import state from.
159 *
160 * Import a sync_file fd into a syncobj handle.
161 */
162void
163syncobj_import_sync_file(int fd, uint32_t handle, int sync_file)
164{
165 struct drm_syncobj_handle args = { 0 };
166 args.handle = handle;
167 args.fd = sync_file;
168 args.flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE;
169 igt_assert_eq(__syncobj_fd_to_handle(fd, &args), 0);
170}
171
172int
173__syncobj_wait(int fd, struct local_syncobj_wait *args)
174{
175 int err = 0;
176 if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_WAIT, args))
177 err = -errno;
178 return err;
179}
180
181int
182syncobj_wait_err(int fd, uint32_t *handles, uint32_t count,
183 uint64_t abs_timeout_nsec, uint32_t flags)
184{
185 struct local_syncobj_wait wait;
186
187 wait.handles = to_user_pointer(handles);
188 wait.timeout_nsec = abs_timeout_nsec;
189 wait.count_handles = count;
190 wait.flags = flags;
191 wait.first_signaled = 0;
192 wait.pad = 0;
193
194 return __syncobj_wait(fd, &wait);
195}
196
197/**
198 * syncobj_wait:
199 * @fd: The DRM file descriptor
200 * @handles: List of syncobj handles to wait for.
201 * @count: Count of handles
202 * @abs_timeout_nsec: Absolute wait timeout in nanoseconds.
203 * @flags: Wait ioctl flags.
204 * @first_signaled: Returned handle for first signaled syncobj.
205 *
206 * Waits in the kernel for any/all the requested syncobjs
207 * using the timeout and flags.
208 * Returns: bool value - false = timedout, true = signaled
209 */
210bool
211syncobj_wait(int fd, uint32_t *handles, uint32_t count,
212 uint64_t abs_timeout_nsec, uint32_t flags,
213 uint32_t *first_signaled)
214{
215 struct local_syncobj_wait wait;
216 int ret;
217
218 wait.handles = to_user_pointer(handles);
219 wait.timeout_nsec = abs_timeout_nsec;
220 wait.count_handles = count;
221 wait.flags = flags;
222 wait.first_signaled = 0;
223 wait.pad = 0;
224
225 ret = __syncobj_wait(fd, &wait);
226 if (ret == ETIME)
227 return false;
228
229 igt_assert_eq(ret, 0);
230 if (first_signaled)
231 *first_signaled = wait.first_signaled;
232
233 return true;
234}
235
236static int
237__syncobj_reset(int fd, uint32_t *handles, uint32_t count)
238{
239 struct local_syncobj_array array = { 0 };
240 int err = 0;
241
242 array.handles = to_user_pointer(handles);
243 array.count_handles = count;
244 if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array))
245 err = -errno;
246 return err;
247}
248
249/**
250 * syncobj_reset:
251 * @fd: The DRM file descriptor.
252 * @handles: Array of syncobj handles to reset
253 * @count: Count of syncobj handles.
254 *
255 * Reset state of a set of syncobjs.
256 */
257void
258syncobj_reset(int fd, uint32_t *handles, uint32_t count)
259{
260 igt_assert_eq(__syncobj_reset(fd, handles, count), 0);
261}
262
263static int
264__syncobj_signal(int fd, uint32_t *handles, uint32_t count)
265{
266 struct local_syncobj_array array = { 0 };
267 int err = 0;
268
269 array.handles = to_user_pointer(handles);
270 array.count_handles = count;
271 if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array))
272 err = -errno;
273 return err;
274}
275
276/**
277 * syncobj_signal:
278 * @fd: The DRM file descriptor.
279 * @handles: Array of syncobj handles to signal
280 * @count: Count of syncobj handles.
281 *
282 * Signal a set of syncobjs.
283 */
284void
285syncobj_signal(int fd, uint32_t *handles, uint32_t count)
286{
287 igt_assert_eq(__syncobj_signal(fd, handles, count), 0);
288}