[Mesa-dev] [PATCH 02/16] util/log: add auto logger facility

Nicolai Hähnle nhaehnle at gmail.com
Wed Aug 16 11:05:32 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

---
 src/gallium/auxiliary/util/u_log.c | 60 ++++++++++++++++++++++++++++++++++++--
 src/gallium/auxiliary/util/u_log.h | 17 +++++++++++
 2 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_log.c b/src/gallium/auxiliary/util/u_log.c
index 6d826f0adda..359b3e10a2e 100644
--- a/src/gallium/auxiliary/util/u_log.c
+++ b/src/gallium/auxiliary/util/u_log.c
@@ -36,13 +36,18 @@ struct u_log_page {
    unsigned max_entries;
 };
 
+struct u_log_auto_logger {
+   u_auto_log_fn *callback;
+   void *data;
+};
+
 /**
  * Initialize the given logging context.
  */
 void
 u_log_context_init(struct u_log_context *ctx)
 {
-   ctx->cur = NULL;
+   memset(ctx, 0, sizeof(*ctx));
 }
 
 /**
@@ -55,7 +60,56 @@ void
 u_log_context_destroy(struct u_log_context *ctx)
 {
    u_log_page_destroy(ctx->cur);
-   ctx->cur = NULL;
+   FREE(ctx->auto_loggers);
+   memset(ctx, 0, sizeof(*ctx));
+}
+
+/**
+ * Add an auto logger.
+ *
+ * Auto loggers are called each time a chunk is added to the log.
+ */
+void
+u_log_add_auto_logger(struct u_log_context *ctx, u_auto_log_fn *callback,
+                      void *data)
+{
+   struct u_log_auto_logger *new_auto_loggers =
+      REALLOC(ctx->auto_loggers,
+              sizeof(*new_auto_loggers) * ctx->num_auto_loggers,
+              sizeof(*new_auto_loggers) * (ctx->num_auto_loggers + 1));
+   if (!new_auto_loggers) {
+      fprintf(stderr, "Gallium u_log: out of memory\n");
+      return;
+   }
+
+   unsigned idx = ctx->num_auto_loggers++;
+   ctx->auto_loggers = new_auto_loggers;
+   ctx->auto_loggers[idx].callback = callback;
+   ctx->auto_loggers[idx].data = data;
+}
+
+/**
+ * Make sure that auto loggers have run.
+ */
+void
+u_log_flush(struct u_log_context *ctx)
+{
+   if (!ctx->num_auto_loggers)
+      return;
+
+   struct u_log_auto_logger *auto_loggers = ctx->auto_loggers;
+   unsigned num_auto_loggers = ctx->num_auto_loggers;
+
+   /* Prevent recursion. */
+   ctx->num_auto_loggers = 0;
+   ctx->auto_loggers = NULL;
+
+   for (unsigned i = 0; i < num_auto_loggers; ++i)
+      auto_loggers[i].callback(auto_loggers[i].data, ctx);
+
+   assert(!ctx->num_auto_loggers);
+   ctx->num_auto_loggers = num_auto_loggers;
+   ctx->auto_loggers = auto_loggers;
 }
 
 static void str_print(void *data, FILE *stream)
@@ -96,6 +150,8 @@ u_log_chunk(struct u_log_context *ctx, const struct u_log_chunk_type *type,
 {
    struct u_log_page *page = ctx->cur;
 
+   u_log_flush(ctx);
+
    if (!page) {
       ctx->cur = CALLOC_STRUCT(u_log_page);
       page = ctx->cur;
diff --git a/src/gallium/auxiliary/util/u_log.h b/src/gallium/auxiliary/util/u_log.h
index d4e6018c9f7..09c47caee55 100644
--- a/src/gallium/auxiliary/util/u_log.h
+++ b/src/gallium/auxiliary/util/u_log.h
@@ -35,6 +35,11 @@
  *
  * Chunks are accumulated into "pages". The manager of the log can periodically
  * take out the current page using \ref u_log_new_page and dump it to a file.
+ *
+ * Furthermore, "auto loggers" can be added to a context, which are callbacks
+ * that are given the opportunity to add their own logging each time a chunk is
+ * added. Drivers can use this to lazily log chunks of their command stream.
+ * Lazy loggers don't need to be re-entrant.
  */
 
 #ifndef U_LOG_H
@@ -45,6 +50,7 @@
 #include "u_debug.h"
 
 struct u_log_page;
+struct u_log_auto_logger;
 
 struct u_log_chunk_type {
    void (*destroy)(void *data);
@@ -53,8 +59,12 @@ struct u_log_chunk_type {
 
 struct u_log_context {
    struct u_log_page *cur;
+   struct u_log_auto_logger *auto_loggers;
+   unsigned num_auto_loggers;
 };
 
+typedef void (u_auto_log_fn)(void *data, struct u_log_context *ctx);
+
 void
 u_log_context_init(struct u_log_context *ctx);
 
@@ -62,6 +72,13 @@ void
 u_log_context_destroy(struct u_log_context *ctx);
 
 void
+u_log_add_auto_logger(struct u_log_context *ctx, u_auto_log_fn *callback,
+                      void *data);
+
+void
+u_log_flush(struct u_log_context *ctx);
+
+void
 u_log_printf(struct u_log_context *ctx, const char *fmt, ...) _util_printf_format(2,3);
 
 void
-- 
2.11.0



More information about the mesa-dev mailing list