Mesa (debug-refcnt): gallium: hook up reference count debugging code

Luca Barbieri lb at kemper.freedesktop.org
Tue Aug 17 23:05:50 UTC 2010


Module: Mesa
Branch: debug-refcnt
Commit: 6dd23b22cfbb9365839ff449470bcf99758fd4b0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6dd23b22cfbb9365839ff449470bcf99758fd4b0

Author: Luca Barbieri <luca at luca-barbieri.com>
Date:   Wed Aug 18 00:41:10 2010 +0200

gallium: hook up reference count debugging code

This commit adds the ability to produce a log file containing all
reference count changes, and object creation/destruction, on Gallium
objects.

The data allows to answer these crucial questions:
1. This game is exhausting all my memory due to a resource leak: where
   is the bug?
2. Which resources is this game using at a given moment?
3. What kinds of resources does this game use?
4. How fast does this game create and destroy resources?

The output is compatible with the one produced by the similar facility
in Mozilla Firefox, allowing to use Mozilla's tools to analyze the data.

To get the log file:
export GALLIUM_REFCNT_LOG=<file>

To get function names and source lines in the log file:
tools/addr2line.sh <file>

To process the log file, see:
http://www.mozilla.org/performance/refcnt-balancer.html

---

 src/gallium/auxiliary/util/u_inlines.h |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 540305c..4dd6b49 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -33,6 +33,8 @@
 #include "pipe/p_state.h"
 #include "pipe/p_screen.h"
 #include "util/u_debug.h"
+#include "util/u_debug_describe.h"
+#include "util/u_debug_refcnt.h"
 #include "util/u_atomic.h"
 #include "util/u_box.h"
 #include "util/u_math.h"
@@ -67,7 +69,7 @@ pipe_is_referenced(struct pipe_reference *reference)
  * \return TRUE if the object's refcount hits zero and should be destroyed.
  */
 static INLINE boolean
-pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
+pipe_reference_described(struct pipe_reference *ptr, struct pipe_reference *reference, void* get_desc)
 {
    boolean destroy = FALSE;
 
@@ -76,6 +78,7 @@ pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
       if (reference) {
          assert(pipe_is_referenced(reference));
          p_atomic_inc(&reference->count);
+         util_debug_reference(reference, get_desc, "AddRef");
       }
 
       if (ptr) {
@@ -83,41 +86,45 @@ pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
          if (p_atomic_dec_zero(&ptr->count)) {
             destroy = TRUE;
          }
+         util_debug_reference(ptr, get_desc, "Release");
       }
    }
 
    return destroy;
 }
 
+static INLINE boolean
+pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
+{
+   return pipe_reference_described(ptr, reference, util_debug_describe_reference);
+}
 
 static INLINE void
 pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
 {
    struct pipe_surface *old_surf = *ptr;
 
-   if (pipe_reference(&(*ptr)->reference, &surf->reference))
+   if (pipe_reference_described(&(*ptr)->reference, &surf->reference, util_debug_describe_surface))
       old_surf->texture->screen->tex_surface_destroy(old_surf);
    *ptr = surf;
 }
 
-
 static INLINE void
 pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex)
 {
    struct pipe_resource *old_tex = *ptr;
 
-   if (pipe_reference(&(*ptr)->reference, &tex->reference))
+   if (pipe_reference_described(&(*ptr)->reference, &tex->reference, util_debug_describe_resource))
       old_tex->screen->resource_destroy(old_tex->screen, old_tex);
    *ptr = tex;
 }
 
-
 static INLINE void
 pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
 {
    struct pipe_sampler_view *old_view = *ptr;
 
-   if (pipe_reference(&(*ptr)->reference, &view->reference))
+   if (pipe_reference_described(&(*ptr)->reference, &view->reference, util_debug_describe_sampler_view))
       old_view->context->sampler_view_destroy(old_view->context, old_view);
    *ptr = view;
 }




More information about the mesa-commit mailing list