root/tools/testing/selftests/sync/sync.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sync_wait
  2. sync_merge
  3. sync_file_info_free
  4. sync_fence_size
  5. sync_fence_count_with_status
  6. sw_sync_timeline_create
  7. sw_sync_timeline_inc
  8. sw_sync_timeline_is_valid
  9. sw_sync_timeline_destroy
  10. sw_sync_fence_create
  11. sw_sync_fence_is_valid
  12. sw_sync_fence_destroy

   1 /*
   2  *  sync / sw_sync abstraction
   3  *  Copyright 2015-2016 Collabora Ltd.
   4  *
   5  *  Based on the implementation from the Android Open Source Project,
   6  *
   7  *  Copyright 2012 Google, Inc
   8  *
   9  *  Permission is hereby granted, free of charge, to any person obtaining a
  10  *  copy of this software and associated documentation files (the "Software"),
  11  *  to deal in the Software without restriction, including without limitation
  12  *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13  *  and/or sell copies of the Software, and to permit persons to whom the
  14  *  Software is furnished to do so, subject to the following conditions:
  15  *
  16  *  The above copyright notice and this permission notice shall be included in
  17  *  all copies or substantial portions of the Software.
  18  *
  19  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23  *  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24  *  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25  *  OTHER DEALINGS IN THE SOFTWARE.
  26  */
  27 
  28 #include <fcntl.h>
  29 #include <malloc.h>
  30 #include <poll.h>
  31 #include <stdint.h>
  32 #include <string.h>
  33 #include <unistd.h>
  34 
  35 #include <sys/ioctl.h>
  36 #include <sys/stat.h>
  37 #include <sys/types.h>
  38 
  39 #include "sync.h"
  40 #include "sw_sync.h"
  41 
  42 #include <linux/sync_file.h>
  43 
  44 
  45 /* SW_SYNC ioctls */
  46 struct sw_sync_create_fence_data {
  47         __u32   value;
  48         char    name[32];
  49         __s32   fence;
  50 };
  51 
  52 #define SW_SYNC_IOC_MAGIC               'W'
  53 #define SW_SYNC_IOC_CREATE_FENCE        _IOWR(SW_SYNC_IOC_MAGIC, 0,\
  54                                               struct sw_sync_create_fence_data)
  55 #define SW_SYNC_IOC_INC                 _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
  56 
  57 
  58 int sync_wait(int fd, int timeout)
  59 {
  60         struct pollfd fds;
  61 
  62         fds.fd = fd;
  63         fds.events = POLLIN | POLLERR;
  64 
  65         return poll(&fds, 1, timeout);
  66 }
  67 
  68 int sync_merge(const char *name, int fd1, int fd2)
  69 {
  70         struct sync_merge_data data = {};
  71         int err;
  72 
  73         data.fd2 = fd2;
  74         strncpy(data.name, name, sizeof(data.name) - 1);
  75         data.name[sizeof(data.name) - 1] = '\0';
  76 
  77         err = ioctl(fd1, SYNC_IOC_MERGE, &data);
  78         if (err < 0)
  79                 return err;
  80 
  81         return data.fence;
  82 }
  83 
  84 static struct sync_file_info *sync_file_info(int fd)
  85 {
  86         struct sync_file_info *info;
  87         struct sync_fence_info *fence_info;
  88         int err, num_fences;
  89 
  90         info = calloc(1, sizeof(*info));
  91         if (info == NULL)
  92                 return NULL;
  93 
  94         err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
  95         if (err < 0) {
  96                 free(info);
  97                 return NULL;
  98         }
  99 
 100         num_fences = info->num_fences;
 101 
 102         if (num_fences) {
 103                 info->flags = 0;
 104                 info->num_fences = num_fences;
 105 
 106                 fence_info = calloc(num_fences, sizeof(*fence_info));
 107                 if (!fence_info) {
 108                         free(info);
 109                         return NULL;
 110                 }
 111 
 112                 info->sync_fence_info = (uint64_t)fence_info;
 113 
 114                 err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
 115                 if (err < 0) {
 116                         free(fence_info);
 117                         free(info);
 118                         return NULL;
 119                 }
 120         }
 121 
 122         return info;
 123 }
 124 
 125 static void sync_file_info_free(struct sync_file_info *info)
 126 {
 127         free((void *)info->sync_fence_info);
 128         free(info);
 129 }
 130 
 131 int sync_fence_size(int fd)
 132 {
 133         int count;
 134         struct sync_file_info *info = sync_file_info(fd);
 135 
 136         if (!info)
 137                 return 0;
 138 
 139         count = info->num_fences;
 140 
 141         sync_file_info_free(info);
 142 
 143         return count;
 144 }
 145 
 146 int sync_fence_count_with_status(int fd, int status)
 147 {
 148         unsigned int i, count = 0;
 149         struct sync_fence_info *fence_info = NULL;
 150         struct sync_file_info *info = sync_file_info(fd);
 151 
 152         if (!info)
 153                 return -1;
 154 
 155         fence_info = (struct sync_fence_info *)info->sync_fence_info;
 156         for (i = 0 ; i < info->num_fences ; i++) {
 157                 if (fence_info[i].status == status)
 158                         count++;
 159         }
 160 
 161         sync_file_info_free(info);
 162 
 163         return count;
 164 }
 165 
 166 int sw_sync_timeline_create(void)
 167 {
 168         return open("/sys/kernel/debug/sync/sw_sync", O_RDWR);
 169 }
 170 
 171 int sw_sync_timeline_inc(int fd, unsigned int count)
 172 {
 173         __u32 arg = count;
 174 
 175         return ioctl(fd, SW_SYNC_IOC_INC, &arg);
 176 }
 177 
 178 int sw_sync_timeline_is_valid(int fd)
 179 {
 180         int status;
 181 
 182         if (fd == -1)
 183                 return 0;
 184 
 185         status = fcntl(fd, F_GETFD, 0);
 186         return (status >= 0);
 187 }
 188 
 189 void sw_sync_timeline_destroy(int fd)
 190 {
 191         if (sw_sync_timeline_is_valid(fd))
 192                 close(fd);
 193 }
 194 
 195 int sw_sync_fence_create(int fd, const char *name, unsigned int value)
 196 {
 197         struct sw_sync_create_fence_data data = {};
 198         int err;
 199 
 200         data.value = value;
 201         strncpy(data.name, name, sizeof(data.name) - 1);
 202         data.name[sizeof(data.name) - 1] = '\0';
 203 
 204         err = ioctl(fd, SW_SYNC_IOC_CREATE_FENCE, &data);
 205         if (err < 0)
 206                 return err;
 207 
 208         return data.fence;
 209 }
 210 
 211 int sw_sync_fence_is_valid(int fd)
 212 {
 213         /* Same code! */
 214         return sw_sync_timeline_is_valid(fd);
 215 }
 216 
 217 void sw_sync_fence_destroy(int fd)
 218 {
 219         if (sw_sync_fence_is_valid(fd))
 220                 close(fd);
 221 }

/* [<][>][^][v][top][bottom][index][help] */