linux/drivers/staging/android/sync.h
<<
>>
Prefs
   1/*
   2 * include/linux/sync.h
   3 *
   4 * Copyright (C) 2012 Google, Inc.
   5 *
   6 * This program is distributed in the hope that it will be useful,
   7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   9 * GNU General Public License for more details.
  10 *
  11 */
  12
  13#ifndef _LINUX_SYNC_H
  14#define _LINUX_SYNC_H
  15
  16#include <linux/types.h>
  17#include <linux/kref.h>
  18#include <linux/ktime.h>
  19#include <linux/list.h>
  20#include <linux/spinlock.h>
  21#include <linux/wait.h>
  22#include <linux/fence.h>
  23
  24#include "uapi/sync.h"
  25
  26struct sync_timeline;
  27struct sync_pt;
  28struct sync_fence;
  29
  30/**
  31 * struct sync_timeline_ops - sync object implementation ops
  32 * @driver_name:        name of the implementation
  33 * @dup:                duplicate a sync_pt
  34 * @has_signaled:       returns:
  35 *                        1 if pt has signaled
  36 *                        0 if pt has not signaled
  37 *                       <0 on error
  38 * @compare:            returns:
  39 *                        1 if b will signal before a
  40 *                        0 if a and b will signal at the same time
  41 *                       -1 if a will signal before b
  42 * @free_pt:            called before sync_pt is freed
  43 * @release_obj:        called before sync_timeline is freed
  44 * @fill_driver_data:   write implementation specific driver data to data.
  45 *                        should return an error if there is not enough room
  46 *                        as specified by size.  This information is returned
  47 *                        to userspace by SYNC_IOC_FENCE_INFO.
  48 * @timeline_value_str: fill str with the value of the sync_timeline's counter
  49 * @pt_value_str:       fill str with the value of the sync_pt
  50 */
  51struct sync_timeline_ops {
  52        const char *driver_name;
  53
  54        /* required */
  55        struct sync_pt * (*dup)(struct sync_pt *pt);
  56
  57        /* required */
  58        int (*has_signaled)(struct sync_pt *pt);
  59
  60        /* required */
  61        int (*compare)(struct sync_pt *a, struct sync_pt *b);
  62
  63        /* optional */
  64        void (*free_pt)(struct sync_pt *sync_pt);
  65
  66        /* optional */
  67        void (*release_obj)(struct sync_timeline *sync_timeline);
  68
  69        /* optional */
  70        int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
  71
  72        /* optional */
  73        void (*timeline_value_str)(struct sync_timeline *timeline, char *str,
  74                                   int size);
  75
  76        /* optional */
  77        void (*pt_value_str)(struct sync_pt *pt, char *str, int size);
  78};
  79
  80/**
  81 * struct sync_timeline - sync object
  82 * @kref:               reference count on fence.
  83 * @ops:                ops that define the implementation of the sync_timeline
  84 * @name:               name of the sync_timeline. Useful for debugging
  85 * @destroyed:          set when sync_timeline is destroyed
  86 * @child_list_head:    list of children sync_pts for this sync_timeline
  87 * @child_list_lock:    lock protecting @child_list_head, destroyed, and
  88 *                        sync_pt.status
  89 * @active_list_head:   list of active (unsignaled/errored) sync_pts
  90 * @sync_timeline_list: membership in global sync_timeline_list
  91 */
  92struct sync_timeline {
  93        struct kref             kref;
  94        const struct sync_timeline_ops  *ops;
  95        char                    name[32];
  96
  97        /* protected by child_list_lock */
  98        bool                    destroyed;
  99        int                     context, value;
 100
 101        struct list_head        child_list_head;
 102        spinlock_t              child_list_lock;
 103
 104        struct list_head        active_list_head;
 105
 106#ifdef CONFIG_DEBUG_FS
 107        struct list_head        sync_timeline_list;
 108#endif
 109};
 110
 111/**
 112 * struct sync_pt - sync point
 113 * @fence:              base fence class
 114 * @child_list:         membership in sync_timeline.child_list_head
 115 * @active_list:        membership in sync_timeline.active_list_head
 116 * @signaled_list:      membership in temporary signaled_list on stack
 117 * @fence:              sync_fence to which the sync_pt belongs
 118 * @pt_list:            membership in sync_fence.pt_list_head
 119 * @status:             1: signaled, 0:active, <0: error
 120 * @timestamp:          time which sync_pt status transitioned from active to
 121 *                        signaled or error.
 122 */
 123struct sync_pt {
 124        struct fence base;
 125
 126        struct list_head        child_list;
 127        struct list_head        active_list;
 128};
 129
 130static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt)
 131{
 132        return container_of(pt->base.lock, struct sync_timeline,
 133                            child_list_lock);
 134}
 135
 136struct sync_fence_cb {
 137        struct fence_cb cb;
 138        struct fence *sync_pt;
 139        struct sync_fence *fence;
 140};
 141
 142/**
 143 * struct sync_fence - sync fence
 144 * @file:               file representing this fence
 145 * @kref:               reference count on fence.
 146 * @name:               name of sync_fence.  Useful for debugging
 147 * @pt_list_head:       list of sync_pts in the fence.  immutable once fence
 148 *                        is created
 149 * @status:             0: signaled, >0:active, <0: error
 150 *
 151 * @wq:                 wait queue for fence signaling
 152 * @sync_fence_list:    membership in global fence list
 153 */
 154struct sync_fence {
 155        struct file             *file;
 156        struct kref             kref;
 157        char                    name[32];
 158#ifdef CONFIG_DEBUG_FS
 159        struct list_head        sync_fence_list;
 160#endif
 161        int num_fences;
 162
 163        wait_queue_head_t       wq;
 164        atomic_t                status;
 165
 166        struct sync_fence_cb    cbs[];
 167};
 168
 169struct sync_fence_waiter;
 170typedef void (*sync_callback_t)(struct sync_fence *fence,
 171                                struct sync_fence_waiter *waiter);
 172
 173/**
 174 * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
 175 * @waiter_list:        membership in sync_fence.waiter_list_head
 176 * @callback:           function pointer to call when fence signals
 177 * @callback_data:      pointer to pass to @callback
 178 */
 179struct sync_fence_waiter {
 180        wait_queue_t work;
 181        sync_callback_t callback;
 182};
 183
 184static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
 185                                          sync_callback_t callback)
 186{
 187        INIT_LIST_HEAD(&waiter->work.task_list);
 188        waiter->callback = callback;
 189}
 190
 191/*
 192 * API for sync_timeline implementers
 193 */
 194
 195/**
 196 * sync_timeline_create() - creates a sync object
 197 * @ops:        specifies the implementation ops for the object
 198 * @size:       size to allocate for this obj
 199 * @name:       sync_timeline name
 200 *
 201 * Creates a new sync_timeline which will use the implementation specified by
 202 * @ops.  @size bytes will be allocated allowing for implementation specific
 203 * data to be kept after the generic sync_timeline struct.
 204 */
 205struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
 206                                           int size, const char *name);
 207
 208/**
 209 * sync_timeline_destroy() - destroys a sync object
 210 * @obj:        sync_timeline to destroy
 211 *
 212 * A sync implementation should call this when the @obj is going away
 213 * (i.e. module unload.)  @obj won't actually be freed until all its children
 214 * sync_pts are freed.
 215 */
 216void sync_timeline_destroy(struct sync_timeline *obj);
 217
 218/**
 219 * sync_timeline_signal() - signal a status change on a sync_timeline
 220 * @obj:        sync_timeline to signal
 221 *
 222 * A sync implementation should call this any time one of it's sync_pts
 223 * has signaled or has an error condition.
 224 */
 225void sync_timeline_signal(struct sync_timeline *obj);
 226
 227/**
 228 * sync_pt_create() - creates a sync pt
 229 * @parent:     sync_pt's parent sync_timeline
 230 * @size:       size to allocate for this pt
 231 *
 232 * Creates a new sync_pt as a child of @parent.  @size bytes will be
 233 * allocated allowing for implementation specific data to be kept after
 234 * the generic sync_timeline struct.
 235 */
 236struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
 237
 238/**
 239 * sync_pt_free() - frees a sync pt
 240 * @pt:         sync_pt to free
 241 *
 242 * This should only be called on sync_pts which have been created but
 243 * not added to a fence.
 244 */
 245void sync_pt_free(struct sync_pt *pt);
 246
 247/**
 248 * sync_fence_create() - creates a sync fence
 249 * @name:       name of fence to create
 250 * @pt:         sync_pt to add to the fence
 251 *
 252 * Creates a fence containg @pt.  Once this is called, the fence takes
 253 * ownership of @pt.
 254 */
 255struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
 256
 257/*
 258 * API for sync_fence consumers
 259 */
 260
 261/**
 262 * sync_fence_merge() - merge two fences
 263 * @name:       name of new fence
 264 * @a:          fence a
 265 * @b:          fence b
 266 *
 267 * Creates a new fence which contains copies of all the sync_pts in both
 268 * @a and @b.  @a and @b remain valid, independent fences.
 269 */
 270struct sync_fence *sync_fence_merge(const char *name,
 271                                    struct sync_fence *a, struct sync_fence *b);
 272
 273/**
 274 * sync_fence_fdget() - get a fence from an fd
 275 * @fd:         fd referencing a fence
 276 *
 277 * Ensures @fd references a valid fence, increments the refcount of the backing
 278 * file, and returns the fence.
 279 */
 280struct sync_fence *sync_fence_fdget(int fd);
 281
 282/**
 283 * sync_fence_put() - puts a reference of a sync fence
 284 * @fence:      fence to put
 285 *
 286 * Puts a reference on @fence.  If this is the last reference, the fence and
 287 * all it's sync_pts will be freed
 288 */
 289void sync_fence_put(struct sync_fence *fence);
 290
 291/**
 292 * sync_fence_install() - installs a fence into a file descriptor
 293 * @fence:      fence to install
 294 * @fd:         file descriptor in which to install the fence
 295 *
 296 * Installs @fence into @fd.  @fd's should be acquired through
 297 * get_unused_fd_flags(O_CLOEXEC).
 298 */
 299void sync_fence_install(struct sync_fence *fence, int fd);
 300
 301/**
 302 * sync_fence_wait_async() - registers and async wait on the fence
 303 * @fence:              fence to wait on
 304 * @waiter:             waiter callback struck
 305 *
 306 * Returns 1 if @fence has already signaled.
 307 *
 308 * Registers a callback to be called when @fence signals or has an error.
 309 * @waiter should be initialized with sync_fence_waiter_init().
 310 */
 311int sync_fence_wait_async(struct sync_fence *fence,
 312                          struct sync_fence_waiter *waiter);
 313
 314/**
 315 * sync_fence_cancel_async() - cancels an async wait
 316 * @fence:              fence to wait on
 317 * @waiter:             waiter callback struck
 318 *
 319 * returns 0 if waiter was removed from fence's async waiter list.
 320 * returns -ENOENT if waiter was not found on fence's async waiter list.
 321 *
 322 * Cancels a previously registered async wait.  Will fail gracefully if
 323 * @waiter was never registered or if @fence has already signaled @waiter.
 324 */
 325int sync_fence_cancel_async(struct sync_fence *fence,
 326                            struct sync_fence_waiter *waiter);
 327
 328/**
 329 * sync_fence_wait() - wait on fence
 330 * @fence:      fence to wait on
 331 * @tiemout:    timeout in ms
 332 *
 333 * Wait for @fence to be signaled or have an error.  Waits indefinitely
 334 * if @timeout < 0
 335 */
 336int sync_fence_wait(struct sync_fence *fence, long timeout);
 337
 338#ifdef CONFIG_DEBUG_FS
 339
 340void sync_timeline_debug_add(struct sync_timeline *obj);
 341void sync_timeline_debug_remove(struct sync_timeline *obj);
 342void sync_fence_debug_add(struct sync_fence *fence);
 343void sync_fence_debug_remove(struct sync_fence *fence);
 344void sync_dump(void);
 345
 346#else
 347# define sync_timeline_debug_add(obj)
 348# define sync_timeline_debug_remove(obj)
 349# define sync_fence_debug_add(fence)
 350# define sync_fence_debug_remove(fence)
 351# define sync_dump()
 352#endif
 353int sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode,
 354                                 int wake_flags, void *key);
 355
 356#endif /* _LINUX_SYNC_H */
 357