bo = bo_from_handle(dev, size, handle);
simple_mtx_unlock(&table_lock);
+ bo->max_fences = 1;
+ bo->fences = &bo->_inline_fence;
+
VG_BO_ALLOC(bo);
return bo;
simple_mtx_assert_locked(&table_lock);
cleanup_fences(bo, false);
- free(bo->fences);
+ if (bo->fences != &bo->_inline_fence)
+ free(bo->fences);
if (bo->map)
os_munmap(bo->map, bo->size);
cleanup_fences(bo, true);
+ /* The first time we grow past a single fence, we need some special
+ * handling, as we've been using the embedded _inline_fence to avoid
+ * a separate allocation:
+ */
+ if (unlikely((bo->nr_fences == 1) &&
+ (bo->fences == &bo->_inline_fence))) {
+ bo->nr_fences = bo->max_fences = 0;
+ bo->fences = NULL;
+ APPEND(bo, fences, bo->_inline_fence);
+ }
+
APPEND(bo, fences, (struct fd_bo_fence){
.pipe = fd_pipe_ref_locked(pipe),
.fence = fence,
time_t free_time; /* time when added to bucket-list */
DECLARE_ARRAY(struct fd_bo_fence, fences);
+
+ /* In the common case, there is no more than one fence attached.
+ * This provides storage for the fences table until it grows to
+ * be larger than a single element.
+ */
+ struct fd_bo_fence _inline_fence;
};
void fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence);