#include "nouveau_dma.h"
#include "nouveau_local.h"
-int
-nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence)
-{
- struct nouveau_fence_priv *nvfence;
-
- if (!chan || !fence || *fence)
- return -EINVAL;
-
- nvfence = calloc(1, sizeof(struct nouveau_fence_priv));
- if (!nvfence)
- return -ENOMEM;
- nvfence->base.channel = chan;
- nvfence->refcount = 1;
-
- *fence = &nvfence->base;
- return 0;
-}
-
-int
-nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence)
-{
- struct nouveau_fence_priv *nvfence;
-
- if (!ref || !fence || *fence)
- return -EINVAL;
- nvfence = nouveau_fence(ref);
- nvfence->refcount++;
-
- *fence = &nvfence->base;
- return 0;
-}
-
static void
nouveau_fence_del_unsignalled(struct nouveau_fence *fence)
{
nvchan->fence_tail = le;
}
-void
+static void
nouveau_fence_del(struct nouveau_fence **fence)
{
struct nouveau_fence_priv *nvfence;
free(nvfence);
}
+int
+nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence)
+{
+ struct nouveau_fence_priv *nvfence;
+
+ if (!chan || !fence || *fence)
+ return -EINVAL;
+
+ nvfence = calloc(1, sizeof(struct nouveau_fence_priv));
+ if (!nvfence)
+ return -ENOMEM;
+ nvfence->base.channel = chan;
+ nvfence->refcount = 1;
+
+ *fence = &nvfence->base;
+ return 0;
+}
+
+int
+nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence)
+{
+ struct nouveau_fence_priv *nvfence;
+
+ if (!fence)
+ return -EINVAL;
+
+ if (*fence) {
+ nouveau_fence_del(fence);
+ *fence = NULL;
+ }
+
+ if (ref) {
+ nvfence = nouveau_fence(ref);
+ nvfence->refcount++;
+ *fence = &nvfence->base;
+ }
+
+ return 0;
+}
+
int
nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *),
void *priv)
uint32_t sequence = *nvchan->ref_cnt;
while (nvchan->fence_head) {
- struct nouveau_fence *fence = NULL;
struct nouveau_fence_priv *nvfence;
- nouveau_fence_ref(nvchan->fence_head, &fence);
nvfence = nouveau_fence(nvchan->fence_head);
-
- if (nvfence->sequence > sequence) {
- nouveau_fence_del(&fence);
+ if (nvfence->sequence > sequence)
break;
- }
nouveau_fence_del_unsignalled(&nvfence->base);
nvfence->signalled = 1;
- while (nvfence->signal_cb) {
- struct nouveau_fence_cb *cb = nvfence->signal_cb;
- nvfence->signal_cb = cb->next;
- cb->func(cb->priv);
- free(cb);
- }
+ if (nvfence->signal_cb) {
+ struct nouveau_fence *fence = NULL;
+
+ nouveau_fence_ref(nvchan->fence_head, &fence);
- nouveau_fence_del(&fence);
+ while (nvfence->signal_cb) {
+ struct nouveau_fence_cb *cb;
+
+ cb = nvfence->signal_cb;
+ nvfence->signal_cb = cb->next;
+ cb->func(cb->priv);
+ free(cb);
+ }
+
+ nouveau_fence_ref(NULL, &fence);
+ }
}
}
while (!nvfence->signalled)
nouveau_fence_flush(nvfence->base.channel);
}
- nouveau_fence_del(fence);
+ nouveau_fence_ref(NULL, fence);
return 0;
}