@Jim: could you please try the attached patch on Mac OS X, and
especially the test mentioned in the commit message?
@Phil: could you do the same thing on CentOS and Ubuntu?
More below in context.
On 2015-02-22 10:39-0000 Phil Rosenberg wrote:
Hi Alan
Great detective work!!!
In response to your question, why do we need a random name? If there
is already an instance of wxPLViewer running or if there is another
example running and we try to create another instance we will try to
generate another region of shared memory with the same name, which
will fail.
So we need some way to make the name unique. I started using rand()
however I didn't want to reseed this global function in case a user
was using it and was relying on a particular seed for reproducibility.
I then moved to using C++ 11 random number generators, because each
generator has it's own seed. However the intel compiler on my Centos
machine didn't support this C++ 11 feature. I thought that something
like a timer might be able to achieve enough randomness that it would
work, obviously not.
I don't know if you have any suggestions where to go from here. As you
say that fix will always give the same sequence, so it won't quite
give the desired effect. A quick google indicates maybe creating my
own (not very good) random number generator might be the way forward,
but other suggestions welcome.
@Phil:
So your requirements are you need a series of names that are
pseudo-randomly different from one nTries to the next, and are not
predictable (i.e, the series of names is different from one invocation
of wxwidgets to the next). That second requirement means all
pseudo-random number generators (such as rand or plrandd) are excluded
unless they are randomly seeded, but random seeding likely requires
a time function so we are back to the solution below.
I think your original idea of using some time or clock function is a good
one, but using the actual clock function for this purpose has two issues.
1. On some platforms (e.g., Debian stable) it is too low resolution so
there are no changes as nTries continues.
2. The man page for clock on Linux has the following note:
"The C standard allows for arbitrary values at the start of the
program; subtract the value returned from a call to clock() at the
start of the program to get maximum portability."
This implies some platforms are also free to start the clock at zero
when the programme commences. From my results I think Debian stable
is one of those so when that is combined with the low resolution,
the AAAAAA and QQQQQQQ results were the only possibilities.
I think the answer to these issues is to use a high-resolution timer
whose zero point is fixed at some epoch (i.e., the Unix epoch) rather
than (potentially) at the start of programme execution. For example, I
notice from the Linux man page that clock_gettime is a POSIX.1-2001
function that returns a struct that contains the number of nanoseconds
since the Unix epoch so I tried that, and it worked fine. See the
attached patch. However, look at the caveats at the end of the
commit message (which is the reason I have not pushed this patch
to master).
The first issue of personal interest to you is does CentOS provide the
clock_gettime functionality? If not, I guess that is a personal
showstopper for you since you are relying on CentOS to give you some
ability to test wxwidgets on fairly up to date enterprise class
distros.
However, I am pretty sure that most if not all Linux distros provide
POSIX.1-2001 capability (14 (!) years later, now) which is all that
should be required to guarantee clock_gettime is available. So I
am hoping your testing of CentOS will be a success.
Furthermore, Windows is apparently not POSIX.1-2001 capable so you
would have to follow up on this patch with using some Windows nanosec
timer functionality in the same way. To research this question you
will likely want to consult
<http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows>.
That discussion includes a demonstration of a clock_gettime clone for
Windows. However, you should probably not use that clone since it is
also alleged that clone only has microseconds resolution (which is
obviously not fine enough resolution), but the discussion also
mentions other Windows alternatives that apparently do deliver nanosec
resolution.
So once you have verified your version of CentOS has clock_gettime (so
you can continue to use it as a test platform) and Ubuntu, and you
have implemented similar use of a nanosec timer in the Windows case,
then we should be good to go for all test platforms between us, and in
that case please push my patch and your Windows followup patch.
However, (see last caveat mentioned in the commit message), we should
also follow up by implementing a CMake test to disable wxwidgets if
the required nanosec timer functionality is not available (i.e., for
super-old Linux distros, super-old proprietary Unices, or super-old
Windows). I volunteer to implement that test once I see your
appropriate commits.
The point of this test is we should not care about or support those
ancient platforms for wxwidgets so long as we have modern Linux,
modern Window, and modern OS X covered, (and for your personal testing
needs a reasonably up-to-date CentOS covered).
Alan
__________________________
Alan W. Irwin
Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.sf.net); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________
Linux-powered Science
__________________________
From e2c8abb48cf38455d7942f4b1eb769520c9710e7 Mon Sep 17 00:00:00 2001
From: "Alan W. Irwin" <air...@users.sourceforge.net>
Date: Sun, 22 Feb 2015 12:45:36 -0800
Subject: [PATCH] wxwidgets device driver: use high-resolution timer to
provide randomized names.
The results of this change give the required unpredictability of names
from one invocation to the next, e.g.,:
examples/c/x01c -debug -dev wxwidgets
[...]
wxPLDevice::SetupMemoryMap: nTries = 0, mapName = plplotMemoryMapJJETIUJXJY
wxPLDevice::SetupMemoryMap: nTries = 0, mutexName = plplotMemoryMapJJETIUJXJYmut
examples/c/x01c -debug -dev wxwidgets
[...]
wxPLDevice::SetupMemoryMap: nTries = 0, mapName = plplotMemoryMapGZUOIZTNDX
wxPLDevice::SetupMemoryMap: nTries = 0, mutexName = plplotMemoryMapGZUOIZTNDXmut
These two invocations worked without issues for nTries = 0, but
from the code further nTries values would have different "random" names as well
so I think this change should be considered a complete success on
Debian stable and all other Unix versions that are compliant
with POSIX.1-2001 (which provides clock_gettime).
However, there are the following caveats:
1. Requires an additional implementation to provide a nanosec
resolution timer on Windows to be used in the same way.
2. Requires a test function to test that the required nanosec
resolution timer function is available on Unix or Windows, and if not
then disable wxwidgets.
---
drivers/wxwidgets_dev.cpp | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/wxwidgets_dev.cpp b/drivers/wxwidgets_dev.cpp
index 181dff6..78298e2 100644
--- a/drivers/wxwidgets_dev.cpp
+++ b/drivers/wxwidgets_dev.cpp
@@ -34,6 +34,8 @@
// std and driver headers
#include <cmath>
+// Needed for clock_gettime
+#include <time.h>
//--------------------------------------------------------------------------
@@ -1085,18 +1087,24 @@ void wxPLDevice::SetupMemoryMap()
{
if ( strlen( m_mfo ) > 0 )
{
- const size_t mapSize = 1024 * 1024;
+ const size_t mapSize = 1024 * 1024;
//create a memory map to hold the data and add it to the array of maps
- int nTries = 0;
- char mapName[PLPLOT_MAX_PATH];
- char mutexName[PLPLOT_MAX_PATH];
+ int nTries = 0;
+ char mapName[PLPLOT_MAX_PATH];
+ char mutexName[PLPLOT_MAX_PATH];
+ struct timespec ts;
while ( nTries < 10 )
{
for ( int i = 0; i < strlen( m_mfo ); ++i )
{
- if ( m_mfo[i] == '?' ) //this is reall a poor imitation of a random number generator.
- mapName[i] = 'A' + (int) ( 26. * plrandd() ); //Using C++11 generators would be better, but are not supported
- //on some enterpise linux systems at the moment
+ if ( m_mfo[i] == '?' )
+ {
+ // This is really a poor imitation of a random number generator.
+ // Using C++11 generators would be better, but are not supported
+ // on some enterprise Linux systems at the moment.
+ clock_gettime( CLOCK_REALTIME, &ts );
+ mapName[i] = 'A' + (int) ( ts.tv_nsec % 26l );
+ }
else
mapName[i] = m_mfo[i];
}
--
1.7.10.4
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel