From 2900c27aef9fb1ae49070f77934ae1887819e753 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 18 Jun 2014 11:14:02 +0200 Subject: rare/interrupts-graph.py: thread for data retrieval This fixes wrong data updates when the UI gets paused (and as a result, the data update gets delayed). --- rare/interrupts-graph.py | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/rare/interrupts-graph.py b/rare/interrupts-graph.py index dce9316..6e4ee23 100755 --- a/rare/interrupts-graph.py +++ b/rare/interrupts-graph.py @@ -6,14 +6,13 @@ # Wishlist: # Thicker legend lines # Nicier smoothing -# split rendering thread from IO thread (otherwise the data is retrieved too -# late when dragging the legend box) import matplotlib.pyplot as plt import matplotlib from collections import deque, OrderedDict import numpy as np from scipy.interpolate import spline, interp1d +import threading # Maximimum number of time units to keep XSCALE = 60 @@ -56,6 +55,16 @@ def is_line_ok(name, yvalues): # Fix Unicode font matplotlib.rc('font', family='DejaVu Sans') +# From http://stackoverflow.com/a/490090 +def synchronized(lock): + """Synchronization decorator.""" + def wrap(f): + def newFunction(*args, **kw): + with lock: + return f(*args, **kw) + return newFunction + return wrap + def get_numbers(): # TODO: may break the graph if a line disappears with open('/proc/interrupts') as pi: @@ -144,14 +153,22 @@ def update_title(): title += ' (paused - press Space to resume)' plt.gcf().canvas.set_window_title(title) +# Lock to avoid updating the UI while the data is being refreshed +data_lock = threading.Lock() +@synchronized(data_lock) +def refresh_data(): + # Update data + for name, n in get_diffs(): + yvalues[name].append(n) + smooth = {} +@synchronized(data_lock) def update(): """Reads new data and updates the line values.""" global update_legend - # Update data + # Update lines for name, n in get_diffs(): ys = yvalues[name] - ys.append(n) # Consider only strictly positive values ydata = [y for y in ys if y > 0] xdata = [i for i, y in enumerate(ys) if y > 0] @@ -232,8 +249,19 @@ def do_draw(): update_title() +# Separate worker for fetching data +def refresh_data_timer(): + global t + t = threading.Timer(INTERVAL, refresh_data_timer) + t.start() + refresh_data() +refresh_data_timer() + while running: if not paused: update() do_draw() plt.pause(INTERVAL) + +# Cancel any scheduled timer +t.cancel() -- cgit v1.2.1