0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <fcntl.h>
0029 #include <malloc.h>
0030 #include <poll.h>
0031 #include <stdint.h>
0032 #include <string.h>
0033 #include <unistd.h>
0034
0035 #include <sys/ioctl.h>
0036 #include <sys/stat.h>
0037 #include <sys/types.h>
0038
0039 #include "sync.h"
0040 #include "sw_sync.h"
0041
0042 #include <linux/sync_file.h>
0043
0044
0045
0046 struct sw_sync_create_fence_data {
0047 __u32 value;
0048 char name[32];
0049 __s32 fence;
0050 };
0051
0052 #define SW_SYNC_IOC_MAGIC 'W'
0053 #define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
0054 struct sw_sync_create_fence_data)
0055 #define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
0056
0057
0058 int sync_wait(int fd, int timeout)
0059 {
0060 struct pollfd fds;
0061
0062 fds.fd = fd;
0063 fds.events = POLLIN | POLLERR;
0064
0065 return poll(&fds, 1, timeout);
0066 }
0067
0068 int sync_merge(const char *name, int fd1, int fd2)
0069 {
0070 struct sync_merge_data data = {};
0071 int err;
0072
0073 data.fd2 = fd2;
0074 strncpy(data.name, name, sizeof(data.name) - 1);
0075 data.name[sizeof(data.name) - 1] = '\0';
0076
0077 err = ioctl(fd1, SYNC_IOC_MERGE, &data);
0078 if (err < 0)
0079 return err;
0080
0081 return data.fence;
0082 }
0083
0084 static struct sync_file_info *sync_file_info(int fd)
0085 {
0086 struct sync_file_info *info;
0087 struct sync_fence_info *fence_info;
0088 int err, num_fences;
0089
0090 info = calloc(1, sizeof(*info));
0091 if (info == NULL)
0092 return NULL;
0093
0094 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
0095 if (err < 0) {
0096 free(info);
0097 return NULL;
0098 }
0099
0100 num_fences = info->num_fences;
0101
0102 if (num_fences) {
0103 info->flags = 0;
0104 info->num_fences = num_fences;
0105
0106 fence_info = calloc(num_fences, sizeof(*fence_info));
0107 if (!fence_info) {
0108 free(info);
0109 return NULL;
0110 }
0111
0112 info->sync_fence_info = (uint64_t)(unsigned long)fence_info;
0113
0114 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
0115 if (err < 0) {
0116 free(fence_info);
0117 free(info);
0118 return NULL;
0119 }
0120 }
0121
0122 return info;
0123 }
0124
0125 static void sync_file_info_free(struct sync_file_info *info)
0126 {
0127 free((void *)(unsigned long)info->sync_fence_info);
0128 free(info);
0129 }
0130
0131 int sync_fence_size(int fd)
0132 {
0133 int count;
0134 struct sync_file_info *info = sync_file_info(fd);
0135
0136 if (!info)
0137 return 0;
0138
0139 count = info->num_fences;
0140
0141 sync_file_info_free(info);
0142
0143 return count;
0144 }
0145
0146 int sync_fence_count_with_status(int fd, int status)
0147 {
0148 unsigned int i, count = 0;
0149 struct sync_fence_info *fence_info = NULL;
0150 struct sync_file_info *info = sync_file_info(fd);
0151
0152 if (!info)
0153 return -1;
0154
0155 fence_info = (struct sync_fence_info *)(unsigned long)info->sync_fence_info;
0156 for (i = 0 ; i < info->num_fences ; i++) {
0157 if (fence_info[i].status == status)
0158 count++;
0159 }
0160
0161 sync_file_info_free(info);
0162
0163 return count;
0164 }
0165
0166 int sw_sync_timeline_create(void)
0167 {
0168 return open("/sys/kernel/debug/sync/sw_sync", O_RDWR);
0169 }
0170
0171 int sw_sync_timeline_inc(int fd, unsigned int count)
0172 {
0173 __u32 arg = count;
0174
0175 return ioctl(fd, SW_SYNC_IOC_INC, &arg);
0176 }
0177
0178 int sw_sync_timeline_is_valid(int fd)
0179 {
0180 int status;
0181
0182 if (fd == -1)
0183 return 0;
0184
0185 status = fcntl(fd, F_GETFD, 0);
0186 return (status >= 0);
0187 }
0188
0189 void sw_sync_timeline_destroy(int fd)
0190 {
0191 if (sw_sync_timeline_is_valid(fd))
0192 close(fd);
0193 }
0194
0195 int sw_sync_fence_create(int fd, const char *name, unsigned int value)
0196 {
0197 struct sw_sync_create_fence_data data = {};
0198 int err;
0199
0200 data.value = value;
0201 strncpy(data.name, name, sizeof(data.name) - 1);
0202 data.name[sizeof(data.name) - 1] = '\0';
0203
0204 err = ioctl(fd, SW_SYNC_IOC_CREATE_FENCE, &data);
0205 if (err < 0)
0206 return err;
0207
0208 return data.fence;
0209 }
0210
0211 int sw_sync_fence_is_valid(int fd)
0212 {
0213
0214 return sw_sync_timeline_is_valid(fd);
0215 }
0216
0217 void sw_sync_fence_destroy(int fd)
0218 {
0219 if (sw_sync_fence_is_valid(fd))
0220 close(fd);
0221 }