diff options
author | Eric Anholt <eric@anholt.net> | 2009-10-20 14:19:38 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-10-20 14:24:44 -0700 |
commit | 0d7ad7e43ca212b1e9f16cd18f36493cab455e61 (patch) | |
tree | 603f238f56e1dde61d6fc4e555887393d4a79dc5 /libdrm | |
parent | 66d2714f5435944a26685be4210e0e0d7138f3db (diff) |
intel: Only call clock_gettime once per unreference_final.
Notably when freeing a batchbuffer, we often end up freeing many of the
buffers it points at as well. Avoiding repeated calls brings us a 9% CPU
win for cairo-gl.
[ # ] backend test min(s) median(s) stddev. count
before:
[ 0] gl firefox-talos-gfx 58.941 58.966 0.75% 3/3
after:
[ 0] gl firefox-talos-gfx 54.186 54.195 0.49% 3/3
Diffstat (limited to 'libdrm')
-rw-r--r-- | libdrm/intel/intel_bufmgr_gem.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index 739c99bd..87795f33 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -188,6 +188,8 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode, uint32_t stride); static void drm_intel_gem_bo_unreference_locked(drm_intel_bo *bo); +static void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo, + time_t time); static void drm_intel_gem_bo_unreference(drm_intel_bo *bo); @@ -708,20 +710,20 @@ drm_intel_gem_cleanup_bo_cache(drm_intel_bufmgr_gem *bufmgr_gem, time_t time) } } -static void drm_intel_gem_bo_unreference_final(drm_intel_bo *bo) +static void +drm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time) { drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; struct drm_intel_gem_bo_bucket *bucket; uint32_t tiling_mode; + int i; - if (bo_gem->relocs != NULL) { - int i; - - /* Unreference all the target buffers */ - for (i = 0; i < bo_gem->reloc_count; i++) - drm_intel_gem_bo_unreference_locked(bo_gem-> - reloc_target_bo[i]); + /* Unreference all the target buffers */ + for (i = 0; i < bo_gem->reloc_count; i++) { + drm_intel_gem_bo_unreference_locked_timed(bo_gem-> + reloc_target_bo[i], + time); } DBG("bo_unreference final: %d (%s)\n", @@ -732,10 +734,7 @@ static void drm_intel_gem_bo_unreference_final(drm_intel_bo *bo) tiling_mode = I915_TILING_NONE; if (bufmgr_gem->bo_reuse && bo_gem->reusable && bucket != NULL && drm_intel_gem_bo_set_tiling(bo, &tiling_mode, 0) == 0) { - struct timespec time; - - clock_gettime(CLOCK_MONOTONIC, &time); - bo_gem->free_time = time.tv_sec; + bo_gem->free_time = time; bo_gem->name = NULL; bo_gem->validate_index = -1; @@ -745,7 +744,7 @@ static void drm_intel_gem_bo_unreference_final(drm_intel_bo *bo) drm_intel_gem_bo_madvise(bufmgr_gem, bo_gem, I915_MADV_DONTNEED); - drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec); + drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time); } else { drm_intel_gem_bo_free(bo); } @@ -756,8 +755,22 @@ static void drm_intel_gem_bo_unreference_locked(drm_intel_bo *bo) drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; assert(atomic_read(&bo_gem->refcount) > 0); + if (atomic_dec_and_test(&bo_gem->refcount)) { + struct timespec time; + + clock_gettime(CLOCK_MONOTONIC, &time); + drm_intel_gem_bo_unreference_final(bo, time.tv_sec); + } +} + +static void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo, + time_t time) +{ + drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; + + assert(atomic_read(&bo_gem->refcount) > 0); if (atomic_dec_and_test(&bo_gem->refcount)) - drm_intel_gem_bo_unreference_final(bo); + drm_intel_gem_bo_unreference_final(bo, time); } static void drm_intel_gem_bo_unreference(drm_intel_bo *bo) @@ -768,8 +781,12 @@ static void drm_intel_gem_bo_unreference(drm_intel_bo *bo) if (atomic_dec_and_test(&bo_gem->refcount)) { drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; + struct timespec time; + + clock_gettime(CLOCK_MONOTONIC, &time); + pthread_mutex_lock(&bufmgr_gem->lock); - drm_intel_gem_bo_unreference_final(bo); + drm_intel_gem_bo_unreference_final(bo, time.tv_sec); pthread_mutex_unlock(&bufmgr_gem->lock); } } |