summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'libsync/sync.c')
-rw-r--r--libsync/sync.c126
1 files changed, 109 insertions, 17 deletions
diff --git a/libsync/sync.c b/libsync/sync.c
index 5946096b0..9ed03dba8 100644
--- a/libsync/sync.c
+++ b/libsync/sync.c
@@ -20,6 +20,8 @@
20#include <malloc.h> 20#include <malloc.h>
21#include <stdint.h> 21#include <stdint.h>
22#include <string.h> 22#include <string.h>
23#include <errno.h>
24#include <poll.h>
23 25
24#include <sys/ioctl.h> 26#include <sys/ioctl.h>
25#include <sys/stat.h> 27#include <sys/stat.h>
@@ -40,43 +42,133 @@ struct sw_sync_create_fence_data {
40 42
41int sync_wait(int fd, int timeout) 43int sync_wait(int fd, int timeout)
42{ 44{
43 __s32 to = timeout; 45 struct pollfd fds;
46 int ret;
47
48 if (fd < 0) {
49 errno = EINVAL;
50 return -1;
51 }
52
53 fds.fd = fd;
54 fds.events = POLLIN;
55
56 do {
57 ret = poll(&fds, 1, timeout);
58 if (ret > 0) {
59 if (fds.revents & (POLLERR | POLLNVAL)) {
60 errno = EINVAL;
61 return -1;
62 }
63 return 0;
64 } else if (ret == 0) {
65 errno = ETIME;
66 return -1;
67 }
68 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
44 69
45 return ioctl(fd, SYNC_IOC_LEGACY_WAIT, &to); 70 return ret;
46} 71}
47 72
48int sync_merge(const char *name, int fd1, int fd2) 73int sync_merge(const char *name, int fd1, int fd2)
49{ 74{
50 struct sync_legacy_merge_data data; 75 struct sync_legacy_merge_data legacy_data;
51 int err; 76 struct sync_merge_data data;
77 int ret;
52 78
53 data.fd2 = fd2; 79 data.fd2 = fd2;
54 strlcpy(data.name, name, sizeof(data.name)); 80 strlcpy(data.name, name, sizeof(data.name));
81 data.flags = 0;
82 data.pad = 0;
55 83
56 err = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &data); 84 ret = ioctl(fd1, SYNC_IOC_MERGE, &data);
57 if (err < 0) 85 if (ret < 0 && errno == ENOTTY) {
58 return err; 86 legacy_data.fd2 = fd2;
87 strlcpy(legacy_data.name, name, sizeof(legacy_data.name));
88
89 ret = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &legacy_data);
90 if (ret < 0)
91 return ret;
92
93 return legacy_data.fence;
94 } else if (ret < 0) {
95 return ret;
96 }
59 97
60 return data.fence; 98 return data.fence;
61} 99}
62 100
63struct sync_fence_info_data *sync_fence_info(int fd) 101struct sync_fence_info_data *sync_fence_info(int fd)
64{ 102{
65 struct sync_fence_info_data *info; 103 struct sync_fence_info_data *legacy_info;
66 int err; 104 struct sync_pt_info *legacy_pt_info;
67 105 struct sync_file_info *info;
68 info = malloc(4096); 106 struct sync_fence_info *fence_info;
69 if (info == NULL) 107 int err, num_fences, i;
108
109 legacy_info = malloc(4096);
110 if (legacy_info == NULL)
70 return NULL; 111 return NULL;
71 112
72 info->len = 4096; 113 legacy_info->len = 4096;
73 err = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info); 114 err = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, legacy_info);
74 if (err < 0) { 115 if (err < 0 && errno != ENOTTY) {
75 free(info); 116 free(legacy_info);
76 return NULL; 117 return NULL;
118 } else if (err == 0) {
119 return legacy_info;
120 }
121
122 info = calloc(1, sizeof(*info));
123 if (info == NULL)
124 goto free;
125
126 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
127 if (err < 0)
128 goto free;
129
130 num_fences = info->num_fences;
131
132 if (num_fences) {
133 info->flags = 0;
134 info->num_fences = num_fences;
135 info->sync_fence_info = (uint64_t) calloc(num_fences,
136 sizeof(struct sync_fence_info));
137 if ((void *)info->sync_fence_info == NULL)
138 goto free;
139
140 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
141 if (err < 0) {
142 free((void *)info->sync_fence_info);
143 goto free;
144 }
145 }
146
147 legacy_info->len = sizeof(*legacy_info) +
148 num_fences * sizeof(struct sync_fence_info);
149 strlcpy(legacy_info->name, info->name, sizeof(legacy_info->name));
150 legacy_info->status = info->status;
151
152 legacy_pt_info = (struct sync_pt_info *)legacy_info->pt_info;
153 fence_info = (struct sync_fence_info *)info->sync_fence_info;
154 for (i = 0 ; i < num_fences ; i++) {
155 legacy_pt_info[i].len = sizeof(*legacy_pt_info);
156 strlcpy(legacy_pt_info[i].obj_name, fence_info[i].obj_name,
157 sizeof(legacy_pt_info->obj_name));
158 strlcpy(legacy_pt_info[i].driver_name, fence_info[i].driver_name,
159 sizeof(legacy_pt_info->driver_name));
160 legacy_pt_info[i].status = fence_info[i].status;
161 legacy_pt_info[i].timestamp_ns = fence_info[i].timestamp_ns;
77 } 162 }
78 163
79 return info; 164 free((void *)info->sync_fence_info);
165 free(info);
166 return legacy_info;
167
168free:
169 free(legacy_info);
170 free(info);
171 return NULL;
80} 172}
81 173
82struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info, 174struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info,