diff --git a/src/freedreno/drm/freedreno_bo.c b/src/freedreno/drm/freedreno_bo.c index e6b37c9f225..0666195868b 100644 --- a/src/freedreno/drm/freedreno_bo.c +++ b/src/freedreno/drm/freedreno_bo.c @@ -273,7 +273,7 @@ fd_bo_mark_for_dump(struct fd_bo *bo) struct fd_bo * fd_bo_ref(struct fd_bo *bo) { - p_atomic_inc(&bo->refcnt); + ref(&bo->refcnt); return bo; } @@ -302,7 +302,7 @@ bo_del_or_recycle(struct fd_bo *bo) void fd_bo_del(struct fd_bo *bo) { - if (!p_atomic_dec_zero(&bo->refcnt)) + if (!unref(&bo->refcnt)) return; struct fd_device *dev = bo->dev; @@ -323,7 +323,7 @@ fd_bo_del_array(struct fd_bo **bos, unsigned count) unsigned cnt = 0; for (unsigned i = 0; i < count; i++) { - if (!p_atomic_dec_zero(&bos[i]->refcnt)) + if (!unref(&bos[i]->refcnt)) continue; if (cnt == ARRAY_SIZE(handles)) { close_handles(dev, handles, cnt); diff --git a/src/freedreno/drm/freedreno_device.c b/src/freedreno/drm/freedreno_device.c index a862c6f5d94..a51b1336e5f 100644 --- a/src/freedreno/drm/freedreno_device.c +++ b/src/freedreno/drm/freedreno_device.c @@ -157,7 +157,7 @@ fd_device_open(void) struct fd_device * fd_device_ref(struct fd_device *dev) { - p_atomic_inc(&dev->refcnt); + ref(&dev->refcnt); return dev; } @@ -171,7 +171,7 @@ fd_device_purge(struct fd_device *dev) void fd_device_del(struct fd_device *dev) { - if (!p_atomic_dec_zero(&dev->refcnt)) + if (!unref(&dev->refcnt)) return; assert(list_is_empty(&dev->deferred_submits)); diff --git a/src/freedreno/drm/freedreno_ringbuffer.c b/src/freedreno/drm/freedreno_ringbuffer.c index 6737e526565..48cd84ad0bf 100644 --- a/src/freedreno/drm/freedreno_ringbuffer.c +++ b/src/freedreno/drm/freedreno_ringbuffer.c @@ -42,7 +42,7 @@ fd_submit_new(struct fd_pipe *pipe) void fd_submit_del(struct fd_submit *submit) { - if (!p_atomic_dec_zero(&submit->refcnt)) + if (!unref(&submit->refcnt)) return; if (submit->primary) @@ -56,7 +56,7 @@ fd_submit_del(struct fd_submit *submit) struct fd_submit * fd_submit_ref(struct fd_submit *submit) { - p_atomic_inc(&submit->refcnt); + ref(&submit->refcnt); return submit; } diff --git a/src/freedreno/drm/freedreno_ringbuffer.h b/src/freedreno/drm/freedreno_ringbuffer.h index fe961e9b7b6..7acb70c0254 100644 --- a/src/freedreno/drm/freedreno_ringbuffer.h +++ b/src/freedreno/drm/freedreno_ringbuffer.h @@ -139,10 +139,33 @@ struct fd_ringbuffer { struct fd_ringbuffer *fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size); +/* + * Helpers for ref/unref with some extra debugging.. unref() returns true if + * the object is still live + */ + +static inline void +ref(int32_t *ref) +{ + ASSERTED int32_t count = p_atomic_inc_return(ref); + /* We should never see a refcnt transition 0->1, this is a sign of a + * zombie coming back from the dead! + */ + assert(count != 1); +} + +static inline bool +unref(int32_t *ref) +{ + int32_t count = p_atomic_dec_return(ref); + assert(count != -1); + return count == 0; +} + static inline void fd_ringbuffer_del(struct fd_ringbuffer *ring) { - if (!p_atomic_dec_zero(&ring->refcnt)) + if (!unref(&ring->refcnt)) return; ring->funcs->destroy(ring); @@ -151,7 +174,7 @@ fd_ringbuffer_del(struct fd_ringbuffer *ring) static inline struct fd_ringbuffer * fd_ringbuffer_ref(struct fd_ringbuffer *ring) { - p_atomic_inc(&ring->refcnt); + ref(&ring->refcnt); return ring; }