[Mesa-dev] [PATCH 1/4] winsys/radeon: Add a millisecond time function

Lauri Kasanen cand at gmx.com
Tue Jan 7 10:11:20 PST 2014


v2: Move to a timing thread to minimize overhead.

Signed-off-by: Lauri Kasanen <cand at gmx.com>
---
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 25 +++++++++++++++++++++++
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 10 +++++++++
 2 files changed, 35 insertions(+)

diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index dc9d183..7bedf92 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -442,6 +442,9 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
     }
     pipe_semaphore_destroy(&ws->cs_queued);
 
+    ws->kill_timing_thread = 1;
+    pipe_thread_wait(ws->timing_thread);
+
     pipe_mutex_destroy(ws->hyperz_owner_mutex);
     pipe_mutex_destroy(ws->cmask_owner_mutex);
     pipe_mutex_destroy(ws->cs_stack_lock);
@@ -596,6 +599,22 @@ static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param)
     return NULL;
 }
 
+static PIPE_THREAD_ROUTINE(radeon_drm_timing_thread, param)
+{
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *) param;
+    uint64_t * const time = &ws->time;
+
+    while (!ws->kill_timing_thread) {
+        uint64_t tmp = os_time_get_nano() / 1000000;
+        p_atomic_set(time, tmp);
+
+        /* We want ms accuracy, so sleep for the Nyquist freq - 0.5ms */
+        usleep(500);
+    }
+
+    return NULL;
+}
+
 DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE)
 static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param);
 
@@ -660,6 +679,12 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd)
     if (ws->num_cpus > 1 && debug_get_option_thread())
         ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);
 
+    /* Set the time once to avoid races - stats_time_get may be called
+     * just after this function returns.
+     */
+    ws->time = os_time_get_nano() / 1000000;
+    ws->timing_thread = pipe_thread_create(radeon_drm_timing_thread, ws);
+
     return &ws->base;
 
 fail:
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index ed90194..01c2d9c 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -32,6 +32,7 @@
 
 #include "radeon_winsys.h"
 #include "os/os_thread.h"
+#include "os/os_time.h"
 
 struct radeon_drm_cs;
 
@@ -71,6 +72,11 @@ struct radeon_drm_winsys {
     int kill_thread;
     int ncs;
     struct radeon_drm_cs *cs_stack[RING_LAST];
+
+    /* Timing thread for the stats. */
+    pipe_thread timing_thread;
+    int kill_timing_thread;
+    uint64_t time;
 };
 
 static INLINE struct radeon_drm_winsys *
@@ -79,6 +85,10 @@ radeon_drm_winsys(struct radeon_winsys *base)
     return (struct radeon_drm_winsys*)base;
 }
 
+static INLINE unsigned long long stats_time_get(struct radeon_drm_winsys * const dws) {
+    return p_atomic_read(&dws->time);
+}
+
 void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs);
 
 #endif
-- 
1.8.3.1



More information about the mesa-dev mailing list