+/**
+ * vmw_fence_seq_is_signaled - Check whether a fence seqno is
+ * signaled.
+ *
+ * @ops: Pointer to a struct pb_fence_ops.
+ *
+ */
+static inline boolean
+vmw_fence_seq_is_signaled(uint32_t seq, uint32_t last, uint32_t cur)
+{
+ return (cur - last <= cur - seq);
+}
+
+
+/**
+ * vmw_fence_ops - Return the vmw_fence_ops structure backing a
+ * struct pb_fence_ops pointer.
+ *
+ * @ops: Pointer to a struct pb_fence_ops.
+ *
+ */
+static inline struct vmw_fence_ops *
+vmw_fence_ops(struct pb_fence_ops *ops)
+{
+ assert(ops);
+ return (struct vmw_fence_ops *)ops;
+}
+
+
+/**
+ * vmw_fences_release - Release all fences from the not_signaled
+ * list.
+ *
+ * @ops: Pointer to a struct vmw_fence_ops.
+ *
+ */
+static void
+vmw_fences_release(struct vmw_fence_ops *ops)
+{
+ struct vmw_fence *fence, *n;
+
+ mtx_lock(&ops->mutex);
+ LIST_FOR_EACH_ENTRY_SAFE(fence, n, &ops->not_signaled, ops_list)
+ LIST_DELINIT(&fence->ops_list);
+ mtx_unlock(&ops->mutex);
+}
+
+/**
+ * vmw_fences_signal - Traverse the not_signaled list and try to
+ * signal unsignaled fences.
+ *
+ * @ops: Pointer to a struct pb_fence_ops.
+ * @signaled: Seqno that has signaled.
+ * @emitted: Last seqno emitted by the kernel.
+ * @has_emitted: Whether we provide the emitted value.
+ *
+ */
+void
+vmw_fences_signal(struct pb_fence_ops *fence_ops,
+ uint32_t signaled,
+ uint32_t emitted,
+ boolean has_emitted)
+{
+ struct vmw_fence_ops *ops = NULL;
+ struct vmw_fence *fence, *n;
+
+ if (fence_ops == NULL)
+ return;
+
+ ops = vmw_fence_ops(fence_ops);
+ mtx_lock(&ops->mutex);
+
+ if (!has_emitted) {
+ emitted = ops->last_emitted;
+ if (emitted - signaled > (1 << 30))
+ emitted = signaled;
+ }
+
+ if (signaled == ops->last_signaled && emitted == ops->last_emitted)
+ goto out_unlock;
+
+ LIST_FOR_EACH_ENTRY_SAFE(fence, n, &ops->not_signaled, ops_list) {
+ if (!vmw_fence_seq_is_signaled(fence->seqno, signaled, emitted))
+ break;
+
+ p_atomic_set(&fence->signalled, 1);
+ LIST_DELINIT(&fence->ops_list);
+ }
+ ops->last_signaled = signaled;
+ ops->last_emitted = emitted;
+
+out_unlock:
+ mtx_unlock(&ops->mutex);
+}
+
+