[cogl] cogl-debug: add instrumentation to track the number of objects



commit 5dc42284a5174d6cb451d0f5956801e67da3e627
Author: Lionel Landwerlin <lionel g landwerlin linux intel com>
Date:   Fri Jun 10 18:44:09 2011 +0100

    cogl-debug: add instrumentation to track the number of objects
    
    This allows to track the number of objects allocated by Cogl. The
    results are displayed on the standard output by calling :
    
    cogl_debug_print_instances ();
    
    Signed-off-by: Lionel Landwerlin <lionel g landwerlin linux intel com>
    Signed-off-by: Neil Roberts <neil linux intel com>

 cogl/cogl-debug.c          |    1 +
 cogl/cogl-debug.h          |    1 +
 cogl/cogl-object-private.h |  123 ++++++++++++++++++++++++++++----------------
 cogl/cogl-object.c         |   32 +++++++++++
 cogl/cogl-object.h         |   73 ++++++++++++++++++++++++++
 5 files changed, 185 insertions(+), 45 deletions(-)
---
diff --git a/cogl/cogl-debug.c b/cogl/cogl-debug.c
index 5b3ecc8..46ab5b4 100644
--- a/cogl/cogl-debug.c
+++ b/cogl/cogl-debug.c
@@ -84,6 +84,7 @@ static const int n_cogl_behavioural_debug_keys =
   G_N_ELEMENTS (cogl_behavioural_debug_keys);
 
 unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS];
+GHashTable *_cogl_debug_instances;
 
 static void
 _cogl_parse_debug_string_for_keys (const char *value,
diff --git a/cogl/cogl-debug.h b/cogl/cogl-debug.h
index 294de84..292de25 100644
--- a/cogl/cogl-debug.h
+++ b/cogl/cogl-debug.h
@@ -75,6 +75,7 @@ typedef enum {
 #define COGL_DEBUG_N_INTS COGL_FLAGS_N_INTS_FOR_SIZE (COGL_DEBUG_N_FLAGS)
 
 extern unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS];
+extern GHashTable *_cogl_debug_instances;
 
 #define COGL_DEBUG_ENABLED(flag) \
   COGL_FLAGS_GET (_cogl_debug_flags, flag)
diff --git a/cogl/cogl-object-private.h b/cogl/cogl-object-private.h
index e8b4ed0..e4c450e 100644
--- a/cogl/cogl-object-private.h
+++ b/cogl/cogl-object-private.h
@@ -123,51 +123,84 @@ struct _CoglObject
 #define _COGL_HANDLE_DEBUG_UNREF _COGL_OBJECT_DEBUG_UNREF
 #define COGL_HANDLE_DEBUG_FREE COGL_OBJECT_DEBUG_FREE
 
-#define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \
-                                                                \
-static CoglObjectClass _cogl_##type_name##_class;               \
-                                                                \
-GQuark                                                          \
-_cogl_object_##type_name##_get_type (void)                      \
-{                                                               \
-  static GQuark type = 0;                                       \
-  if (!type)                                                    \
-    {                                                           \
-      type = g_quark_from_static_string ("Cogl"#TypeName);      \
-      { code; }                                                 \
-    }                                                           \
-  return type;                                                  \
-}                                                               \
-                                                                \
-GQuark                                                          \
-_cogl_handle_##type_name##_get_type (void)                      \
-{                                                               \
-  return _cogl_object_##type_name##_get_type ();                \
-}                                                               \
-                                                                \
-static Cogl##TypeName *                                         \
-_cogl_##type_name##_object_new (Cogl##TypeName *new_obj)        \
-{                                                               \
-  CoglObject *obj = (CoglObject *)&new_obj->_parent;            \
-  obj->ref_count = 1;                                           \
-  obj->n_user_data_entries = 0;                                 \
-  obj->user_data_array = NULL;                                  \
-                                                                \
-  obj->klass = &_cogl_##type_name##_class;                      \
-  if (!obj->klass->type)                                        \
-    {                                                           \
-      obj->klass->type = _cogl_object_##type_name##_get_type ();\
-      obj->klass->virt_free = _cogl_##type_name##_free;         \
-    }                                                           \
-                                                                \
-  _COGL_OBJECT_DEBUG_NEW (TypeName, obj);                       \
-  return new_obj;                                               \
-}                                                               \
-                                                                \
-Cogl##TypeName *                                                \
-_cogl_##type_name##_pointer_from_handle (CoglHandle handle)     \
-{                                                               \
-  return handle;                                                \
+#define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code)  \
+                                                                        \
+static CoglObjectClass _cogl_##type_name##_class;                       \
+static unsigned long _cogl_object_##type_name##_count;                  \
+                                                                        \
+static inline void                                                      \
+_cogl_object_##type_name##_inc (void)                                   \
+{                                                                       \
+  _cogl_object_##type_name##_count++;                                   \
+}                                                                       \
+                                                                        \
+static inline void                                                      \
+_cogl_object_##type_name##_dec (void)                                   \
+{                                                                       \
+  _cogl_object_##type_name##_count--;                                   \
+}                                                                       \
+                                                                        \
+static void                                                             \
+_cogl_object_##type_name##_indirect_free (CoglObject *obj)              \
+{                                                                       \
+  _cogl_##type_name##_free ((Cogl##TypeName *) obj);                    \
+  _cogl_object_##type_name##_dec ();                                    \
+}                                                                       \
+                                                                        \
+GQuark                                                                  \
+_cogl_object_##type_name##_get_type (void)                              \
+{                                                                       \
+  static GQuark type = 0;                                               \
+  if (!type)                                                            \
+    {                                                                   \
+      type = g_quark_from_static_string ("Cogl"#TypeName);              \
+      _cogl_object_##type_name##_count = 0;                             \
+                                                                        \
+      if (_cogl_debug_instances == NULL)                                \
+        _cogl_debug_instances =                                         \
+          g_hash_table_new (g_str_hash, g_str_equal);                   \
+                                                                        \
+      g_hash_table_insert (_cogl_debug_instances,                       \
+                           "Cogl"#TypeName,                             \
+                           &_cogl_object_##type_name##_count);          \
+                                                                        \
+      { code; }                                                         \
+    }                                                                   \
+  return type;                                                          \
+}                                                                       \
+                                                                        \
+GQuark                                                                  \
+_cogl_handle_##type_name##_get_type (void)                              \
+{                                                                       \
+  return _cogl_object_##type_name##_get_type ();                        \
+}                                                                       \
+                                                                        \
+static Cogl##TypeName *                                                 \
+_cogl_##type_name##_object_new (Cogl##TypeName *new_obj)                \
+{                                                                       \
+  CoglObject *obj = (CoglObject *)&new_obj->_parent;                    \
+  obj->ref_count = 0;                                                   \
+  cogl_object_ref (obj);                                                \
+  obj->n_user_data_entries = 0;                                         \
+  obj->user_data_array = NULL;                                          \
+                                                                        \
+  obj->klass = &_cogl_##type_name##_class;                              \
+  if (!obj->klass->type)                                                \
+    {                                                                   \
+      obj->klass->type = _cogl_object_##type_name##_get_type ();        \
+      obj->klass->virt_free =                                           \
+        _cogl_object_##type_name##_indirect_free;                       \
+    }                                                                   \
+                                                                        \
+  _cogl_object_##type_name##_inc ();                                    \
+  _COGL_OBJECT_DEBUG_NEW (TypeName, obj);                               \
+  return new_obj;                                                       \
+}                                                                       \
+                                                                        \
+Cogl##TypeName *                                                        \
+_cogl_##type_name##_pointer_from_handle (CoglHandle handle)             \
+{                                                                       \
+  return handle;                                                        \
 }
 
 #define COGL_OBJECT_DEFINE_WITH_CODE(TypeName, type_name, code)         \
diff --git a/cogl/cogl-object.c b/cogl/cogl-object.c
index 90109eb..4180056 100644
--- a/cogl/cogl-object.c
+++ b/cogl/cogl-object.c
@@ -247,3 +247,35 @@ cogl_object_get_user_data (CoglObject *object, CoglUserDataKey *key)
   return NULL;
 }
 
+void
+cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func,
+                                void *user_data)
+{
+  GHashTableIter iter;
+  unsigned long *instance_count;
+  CoglDebugObjectTypeInfo info;
+
+  g_hash_table_iter_init (&iter, _cogl_debug_instances);
+  while (g_hash_table_iter_next (&iter,
+                                 (void *) &info.name,
+                                 (void *) &instance_count))
+    {
+      info.instance_count = *instance_count;
+      func (&info, user_data);
+    }
+}
+
+static void
+print_instances_cb (const CoglDebugObjectTypeInfo *info,
+                    void *user_data)
+{
+  g_print ("\t%s: %lu\n", info->name, info->instance_count);
+}
+
+void
+cogl_debug_object_print_instances (void)
+{
+  g_print ("Cogl instances:\n");
+
+  cogl_debug_object_foreach_type (print_instances_cb, NULL);
+}
diff --git a/cogl/cogl-object.h b/cogl/cogl-object.h
index 71dd8bd..f948c7f 100644
--- a/cogl/cogl-object.h
+++ b/cogl/cogl-object.h
@@ -82,6 +82,37 @@ typedef struct
 typedef void (*CoglUserDataDestroyCallback) (void *user_data);
 
 /**
+ * CoglDebugObjectTypeInfo:
+ * @name: A human readable name for the type.
+ * @instance_count: The number of objects of this type that are
+ *   currently in use
+ *
+ * This struct is used to pass information to the callback when
+ * cogl_debug_object_foreach_type() is called.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+typedef struct
+{
+  const char *name;
+  unsigned long instance_count;
+} CoglDebugObjectTypeInfo;
+
+/**
+ * CoglDebugObjectForeachTypeCallback:
+ * @info: A pointer to a struct containing information about the type.
+ *
+ * A callback function to use for cogl_debug_object_foreach_type().
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+typedef void
+(* CoglDebugObjectForeachTypeCallback) (const CoglDebugObjectTypeInfo *info,
+                                        void *user_data);
+
+/**
  * cogl_object_set_user_data: (skip)
  * @object: The object to associate private data with
  * @key: The address of a #CoglUserDataKey which provides a unique value
@@ -123,5 +154,47 @@ cogl_object_set_user_data (CoglObject *object,
 void *
 cogl_object_get_user_data (CoglObject *object,
                            CoglUserDataKey *key);
+
+#ifdef COGL_ENABLE_EXPERIMENTAL_API
+
+#define cogl_debug_object_foreach_type \
+  cogl_debug_object_foreach_type_EXP
+
+/**
+ * cogl_debug_object_foreach_type:
+ * func: A callback function for each type
+ * user_data: A pointer to pass to @func
+ *
+ * Invokes @func once for each type of object that Cogl uses and
+ * passes a count of the number of objects for that type. This is
+ * intended to be used solely for debugging purposes to track down
+ * issues with objects leaking.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+void
+cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func,
+                                void *user_data);
+
+#define cogl_debug_object_print_instances \
+  cogl_debug_object_print_instances_EXP
+
+/**
+ * cogl_debug_object_print_instances:
+ *
+ * Prints a list of all the object types that Cogl uses along with the
+ * number of objects of that type that are currently in use. This is
+ * intended to be used solely for debugging purposes to track down
+ * issues with objects leaking.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+void
+cogl_debug_object_print_instances (void);
+
+#endif /* COGL_ENABLE_EXPERIMENTAL_API */
+
 #endif /* __COGL_OBJECT_H */
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]