A Real-Time Data Plotting Program
In order to understand how the X socket, other sockets and timers are prioritized, we have to look into the Qt source. Troll makes the Qt source freely available (see Resources for the URL). The code we want is in /src/kernel/qapplication_x11.cpp, under the distribution tree. Note that while Qt source is freely redistributable, Troll's license prohibits modification, unlike the GPL.
The function QApplication::processNextEvent, which is called by the main event loop, services the X socket, QSocketNotifier sockets and QTimer timers. QApplication::processNextEvent first checks for an X event to process. If none is found, it enters the select system call.
After select returns, QApplication::processNextEvent dispatches events to all QSocketNotifier objects whose file descriptors are ready. It then dispatches events to all QTimers whose timeouts have been reached. The event loop for Qt 1.44 can be summarized as follows (fd stands for file descriptor):
while (1)
{
if (X event pending) {
dispatch X event;
continue;
}
timeout = minimum of all QTimer times to
next event;
select (X fd, all QSocketNotifier fd's,
timeout);
dispatch events to all QSocketNotifier's with
active sockets;
dispatch events to all QTimer's with expired
times;
}
Note that X events get highest priority, in the sense that as long as there are more X events, the loop will ignore the QSocketNotifier's and QTimer's events. However, when an X event is not available, it is possible that Qt will execute every QSocketNotifier and QTimer event before returning to X events. This means we must consider the sum of registered QSocketNotifier and QTimer event processing times as the worst-case user interface latency.
From here on, I will refer to the rtp code in some detail. You may want to download the code from the URL given earlier and print it out with line numbers.
All of rtp's non-automatic data structures are embedded within two primary C++ classes. PlotWindow is derived from Qt's QWidget and provides all user interface callbacks, as well as the STDIN callback. These classes are laid out in rtp.h. The important data members of PlotWindow are:
deque<DoubPt> _points: the entire set of raw (x,y) data points received from stdin. deque is a C++ Standard Template Library class that (among other things) gives the illusion of contiguous memory layout (array indices, fake pointers that you can increment to move through the deque) to a dynamically sized block-linked data structure. Points are kept in the order in which they are received.
QPixmap *_buffer: the pixmap that is copied into the plot window whenever the window is painted.
RtpMapping _map: holds the viewport boundaries, scale factors and offsets currently in effect for mapping received data points into the plot window.
QRect *_rubberBox: if non-NULL, defines the “rubber” box that the user is bounding with the mouse to define a new viewport. Once the user releases the mouse, the box will be deleted from the screen and the viewport will change.
The other important rtp class is RtpRender. Its important data members are:
QTimer _timer: activated to call RtpRender::slotWorkAwhile while a rendering is in progress. Inactive when rendering is not in progress.
unsigned int _pti: marks the position in points as successive calls to RtpRender::slotWorkAwhile progress through the data.
QPixMap *_privateBuff: *_buf. _privateBuff will be created for a private rendering (explained below). _buf is the pixmap actually drawn into by RtpRender::slotWorkAwhile. It will equal either _privateBuff for a private rendering or the main repaint pixmap for an on-line rendering.
Data points to plot come in on STDIN. As part of its initial setup, rtp sets the STDIN file descriptor mode to non-blocking so that any read of STDIN will not block the program. This allows us to read stdin in relatively large chunks, increasing efficiency. rtp then creates a QSocketNotifier for STDIN, registering PlotWindow::slotStdinAwake as the callback through the signal/slot mechanism. Here is the code, from line 454 of rtp.c:
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); QSocketNotifier sn(STDIN_FILENO, QSocketNotifier::Read); QObject::connect(&sn, SIGNAL(activated(int)), plotter, SLOT(slotStdinAwake()));
When slotStdinAwake (rtp.c, line 100) is called, we know there is at least one character of data on STDIN (because select returned with STDIN marked as ready, and all POSIX I/O is character-based). However, simply reading one character and then returning is very inefficient. For optimal efficiency, we want to read and process as many characters as possible.
However, the time spent in slotStdinAwake contributes to the user interface latency, because no X events can be processed until slotStdinAwake exits. If we processed as many STDIN characters as were available and STDIN was receiving points at a faster rate than they could be processed, we could risk locking out the UI (user interface) completely. So we have a classic tradeoff between efficiency and latency. The current version of rtp attempts to read and process 1024 characters of data per slotStdinAwake call. However, because the read call doesn't block, we may not actually process this many characters.
slotStdinAwake is uglified by the fact that it does its own buffering and doesn't use the STDIO library. I couldn't tell from the GNU libc information whether STDIO would work after O_NONBLOCK had been set on the descriptor. Rather than find out, I took the lazy approach and wrote my own buffering code.
When rtp parses a new x,y data point, it will map it into the current pixmap if it is within the current viewport's range. If the point is out of range and the plot mode is auto-scale or auto-tracking, the entire plot must be redrawn at a new scaling and offset. The code in Listing 1 (rtp.c, line 255) handles these cases.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Designing Electronics with Linux
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Build a Skype Server for Your Home Phone System
- New Products
- A Topic for Discussion - Open Source Feature-Richness?
- Why Python?
- Validate an E-Mail Address with PHP, the Right Way
- Tech Tip: Really Simple HTTP Server with Python
- Great
7 min 39 sec ago - Reply to comment | Linux Journal
15 min 40 sec ago - Understanding the Linux Kernel
2 hours 30 min ago - General
5 hours 5 sec ago - Kernel Problem
15 hours 2 min ago - BASH script to log IPs on public web server
19 hours 29 min ago - DynDNS
23 hours 5 min ago - Reply to comment | Linux Journal
23 hours 38 min ago - All the articles you talked
1 day 2 hours ago - All the articles you talked
1 day 2 hours ago




Comments
bad link
http://www.linuxjournal.com/article/3921
refers to rtp 1.0.0. Link is broken, version is 1.0.1
ftp://metalab.unc.edu/pub/linux/science/visualization/rtp-1.0.1.tar.gz