summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-10-20 14:19:38 -0700
committerEric Anholt <eric@anholt.net>2009-10-20 14:24:44 -0700
commit0d7ad7e43ca212b1e9f16cd18f36493cab455e61 (patch)
tree603f238f56e1dde61d6fc4e555887393d4a79dc5
parent66d2714f5435944a26685be4210e0e0d7138f3db (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
-rw-r--r--libdrm/intel/intel_bufmgr_gem.c47
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);
}
}