1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
|
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3//EN">
<HTML><HEAD>
<TITLE>IBM Visualization Data Explorer Programmer's Reference</TITLE>
<META HTTP-EQUIV="abstract" CONTENT="IBM Visualization Data Explorer
Programmer's Reference">
<META HTTP-EQUIV="contact" CONTENT="IBM Visualization Data Explorer
(ibmdx@watson.ibm.com)">
<META HTTP-EQUIV="owner" CONTENT="IBM Visualization Data Explorer
(ibmdx@watson.ibm.com)">
<META HTTP-EQUIV="updated" CONTENT="Tue, 16 Sep 1997 ">
<META HTTP-EQUIV="review" CONTENT="Fri, 14 Aug 1998 ">
<META HTTP-EQUIV="keywords" CONTENT="GRAPHICS VISUALIZATION VISUAL PROGRAM DATA
MINING">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</HEAD><BODY BGCOLOR="#FFFFFF">
<A NAME="Top_Of_Page"></A>
<H1>IBM Visualization Data Explorer Programmer's Reference</H1>
<B>[ <A HREF="#Bot_Of_Page">Bottom of Page</A> | <A
HREF="progu040.htm">Previous Page</A> | <A HREF="progu042.htm">Next
Page</A> | <A HREF="../proguide.htm#ToC">Table of Contents</A> | <A
HREF="progu037.htm#PToC13">Partial Table of Contents</A> | <A
HREF="progu344.htm#HDRINDEX_START">Index</A> ]</B><HR><P>
<HR>
<H2><A NAME="HDRCLO2" HREF="progu037.htm#PToC_80">11.5 Compiling, Linking, and
Debugging an Outboard Module</A></H2>
<A NAME="IDX345"></A>
<A NAME="IDX346"></A>
<A NAME="IDX347"></A>
<A NAME="IDX348"></A>
<A NAME="IDX349"></A>
<A NAME="IDX350"></A>
<A NAME="IDX351"></A>
<P>
The following sample makefile templates for creating outboard modules
can be found in <TT><STRONG>/usr/share/dx/samples/user</STRONG></TT>:
<A NAME="IDX352"></A>
<A NAME="IDX353"></A>
<A NAME="IDX354"></A>
<A NAME="IDX355"></A>
<A NAME="IDX356"></A>
<A NAME="IDX357"></A>
<UL COMPACT>
<LI>RISC System/6000* Systems:
<TT><STRONG>Makefile_outboard_ibm6000</STRONG></TT>
<LI>Silicon Graphics**:
<TT><STRONG>Makefile_outboard_sgi</STRONG></TT>
<LI>Sun Microsystems**:
<TT><STRONG>Makefile_outboard_solaris</STRONG></TT> or
<TT><STRONG>Makefile_outboard_sun4</STRONG></TT>
<LI>Hewlett-Packard**:
<TT><STRONG>Makefile_outboard_hp700</STRONG></TT>
<LI>Data General AViiON**:
<TT><STRONG>Makefile_outboard_aviion</STRONG></TT>
<LI>DEC Alpha**:
<TT><STRONG>Makefile_outboard_alphax</STRONG></TT>
</UL>
<P>
Replace <TT><STRONG>makex.o</STRONG></TT>, <TT><STRONG>add.o</STRONG></TT>, and
<TT><STRONG>hello.o</STRONG></TT> with the names of your
<TT><STRONG>.o</STRONG></TT> files;
replace <TT><STRONG>m_Hello</STRONG></TT>, etc. with the names of your
modules;
and replace <TT><STRONG>hello</STRONG></TT>, etc. with the names you want
for your executables.
The .mdf file for the outboard modules is
<TT><STRONG>user_outboard.mdf</STRONG></TT>.
<TABLE BORDER WIDTH="100%"><TR><TH ALIGN="LEFT">Linking Outboard
Modules</TH><TR><TD>
<P>
Typically outboard modules are linked to the library dxlite, which
contains the Data Explorer data model routines (see
<A HREF="progu096.htm#HDRDXLAP1">Appendix B. "Data Explorer Data Model Library:
DXlite Routines"</A>).
This library does not contain all of the Data Explorer routines (see
<A HREF="progu097.htm#HDRALLR">Appendix C. "Data Explorer Library
Routines"</A>), and an outboard module requiring access
to such "additional" routines must be linked to the
library dxcallm.
However, the resulting outboard executable will be significantly
larger than it would be otherwise.
</TD></TR></TABLE>
<P>
Starting Data Explorer requires specifying the .mdf file to the user
interface:
<PRE>
dx -mdf my.mdf
</PRE>
<P><B>Notes: </B><OL>
<P><LI>You can also load a .mdf. file after Data Explorer has
started.
Use the <TT><STRONG>Load Module Description(s)</STRONG></TT> option in the
<TT><STRONG>File</STRONG></TT> pull-down menu of the VPE window.
<P><LI>In script mode, Data Explorer does not recognize the -mdf flag, so you
must
add the following commands to your script before calling the module:
<PRE>
Executive("mdf file", "module_name.mdf");
$sync
</PRE>
</OL>
<P>
To debug a module you must first modify the CFLAGS line of the makefile
to compile your source code as debuggable (<TT><STRONG>-g</STRONG></TT>)
rather than optimized (<TT><STRONG>-O</STRONG></TT>).
<P><B>Note: </B>Data Explorer library routines are available only as optimized
object code.
<P>
To debug a module, start Data Explorer with the additional flag
<TT>-outboarddebug</TT>.
Instead of automatically starting the module, Data Explorer will prompt you
to start the executable.
You can then run the module from a debugger,
using the flags specified to you by Data Explorer when it prompts you to start
the module.
<P>
<H3><A NAME="Header_81" HREF="progu037.htm#PToC_81">Special Considerations for
Outboard Modules</A></H3>
<A NAME="IDX358"></A>
<A NAME="IDX359"></A>
<P>
<H4><A NAME="Header_82">Simple outboard modules</A></H4>
<A NAME="IDX360"></A>
<A NAME="IDX361"></A>
<A NAME="IDX362"></A>
<P>
The simplest type of outboard module does not need to save information,
does not communicate with any other process, and does not
cause asynchronous executions.
It takes inputs, computes something based on them, and returns
outputs.
The executable program that makes up the outboard module is run each
time the module is called, and it exits after returning the
output values.
<P>
<H4><A NAME="Header_83">Persistent outboard modules</A></H4>
<A NAME="IDX363"></A>
<A NAME="IDX364"></A>
<A NAME="IDX365"></A>
<P>
To prevent the executable program of the outboard module from exiting
after each execution, set the PERSISTENT flag on the FLAGS line
in its <TT><STRONG>.mdf</STRONG></TT> file.
This setting may be necessary so that the module can save information
from one execution to another, or because repeated exits and
restarts take too much time.
<P>
A persistent outboard module is started from the user interface the
first time the module is called and does not exit until its
icon is deleted from the network (program), the entire
network is deleted, or the <TT><STRONG>Reset Server</STRONG></TT>
option is selected from the <TT><STRONG>Connection</STRONG></TT>
pull-down menu.
<P>
In script mode, persistent outboard modules are loaded the first time
they are called and they do not exit until the executive
exits or the command
<PRE>
Executive ("flush dictionary");
</PRE>
is run.
<P>
Global variables can be safely used to save information between
executions of an outboard module.
If the same outboard module occurs in a network more than once, a
different process is started for each occurrence.
<P>
Note that the module may not be called at every
execution:
If the inputs are changed from their original values and then back
again, Data Explorer saves the previous results and uses them without
recalling the module.
The "cache none" option prevents previous results from being
saved, but you also need to set "cache none" for all
downstream modules that process the outputs.
Otherwise, caching at the lower levels will still prevent the module
from being called each time.
The SIDE_EFFECT flag specifies that the module is to be called each
time, the performance penalty being that the module continues to
execute even if the inputs remain unchanged.
<P>
<H4><A NAME="Header_84">Modules that can cause executions:</A></H4>
<P>
An asynchronous module can request that it be rerun.
See <A HREF="progu038.htm#HDRASYNMOD">11.2 , "Asynchronous Modules"</A>.
<P>
<H4><A NAME="Header_85">Running an outboard on another machine:</A></H4>
<P>
If an outboard module should be run on one particular machine
(perhaps because it is compute intensive and needs to run on a fast
machine, or because it needs to access a peripheral that is
connected to only one machine), the OUTBOARD line can specify a host
name as well as an executable name. The Data Explorer libraries will take care
of establishing a connection between where the main Data Explorer executive is
running and the outboard host machine. The DXMODULES environment
variable or the -modules flag can be used to specify a search path
for outboard module executables, or the OUTBOARD line can
specify a fully qualified path name.
<P>
A valid .rhosts file must be present to allow Data Explorer to use the
"rsh" command to start a process on another machine.
(See the UNIX manual page for "rsh" or "remsh" for more
information.)
<P>
<H4><A NAME="Header_86">Miscellaneous information</A></H4>
<P>
DXReadyToRun cannot be called from the time a module receives its
inputs until after it returns its outputs.
To trigger another execution immediately, it can do so after the call
to DXCallOutboard() in the outboard.c file.
<P>
Outboard modules cannot be written in coroutine style. They cannot
produce outputs without being called by Data Explorer and thereby receiving new
inputs (which can be ignored), and they must return something - the main
Data Explorer executive will wait for the module to return before continuing.
<P>
An asynchronous module cannot be run in distributed mode, but it can be
executed on another machine by setting the host name on the
OUTBOARD line.
<P>
<H3><A NAME="Header_87" HREF="progu037.htm#PToC_87">Asynchronous Outboard
Module: An Example</A></H3>
<A NAME="IDX366"></A>
<A NAME="IDX367"></A>
<A NAME="IDX368"></A>
<A NAME="IDX369"></A>
<P>
The function of this example module is to monitor the status of a
given file.
Whenever the file is modified, its data are reimported.
For example, this program could be used to monitor the output of a
simulation program.
The data can be plotted as they are created.
<P>
This sample program is /usr/share/dx/samples/outboard/watchfile.c.
The same directory also holds the associated .mdf file
(<TT>watchfile.mdf</TT>) and an example (<TT>watchsocket.c</TT>)
that listens for input over a socket.
See /usr/share/dx/samples/Outboard/Readme for more information abut
sample modules.
<PRE>
/*
* sample asynchronous outboard module.
*
* uses a signal to ask to be woken after a certain delay.
* if a given file has been changed, re-import the data.
*
* see watchfile.mdf, which must be loaded before this can be run.
* also see Makefile_architecture.name for how to compile this.
*/
#include <dx/dx.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <sys/stat.h>
static Pointer id = NULL;
static time_t lastchanged;
static int seconds;
static char filename[1024];
</PRE>
<PRE>
/*
* this routine is called each time the alarm signal is
* issued.
*/
void signalcatch()
{
struct stat Buffer;
time_t changed;
/* stat the file to find out its last modification time */
if (stat(filename, &Buffer) == 0)
{
/* the last time the file was changed */
changed = Buffer.st_mtime;
/* compare to the last time the file was checked */
if (lastchanged != changed)
{
/* the file has changed. Rerun the main program. */
DXReadyToRun(id);
}
</PRE>
<PRE>
/* else the file hasn't changed since last time we checked */
else
{
/* go back to sleep for some seconds, but first reset the
* alarm */
signal(SIGALRM, signalcatch);
alarm(seconds);
}
}
}
</PRE>
<PRE>
Error
m_WatchFile(Object *in, Object *out)
{
struct stat Buffer;
char *file;
/* the first input is the filename to check */
if (!in[0])
{
DXSetError(ERROR_MISSING_DATA,"missing filename");
return ERROR;
}
if (!DXExtractString(in[0], &file))
{
DXSetError(ERROR_BAD_PARAMETER,"filename must be a string");
return ERROR;
}
</PRE>
<PRE>
/* put the filename into a static global variable */
strcpy(filename,file);
/* the second input is the number of seconds to wait between checks */
/* the default is 10 seconds */
if (!in[1])
seconds = 10;
else
{
if (!DXExtractInteger(in[1], &seconds))
{
DXSetError(ERROR_BAD_PARAMETER,"seconds must be an integer");
return ERROR;
}
}
</PRE>
<PRE>
/* the first time through, get the module id for the DXReadyToRun call */
if (!id) {
id = DXGetModuleId();
if (!id) {
out[0] = NULL;
return ERROR;
}
}
/* get the last modification time of the file */
if (stat(filename, &Buffer) != 0) {
DXSetError(ERROR_BAD_PARAMETER,"file %s not found");
return ERROR;
}
lastchanged = Buffer.st_mtime;
</PRE>
<PRE>
/* import the data from the file */
out[0] = DXImportDX(filename, NULL, NULL, NULL, NULL);
/* set the alarm for the next wakeup */
signal(SIGALRM, signalcatch);
alarm(seconds);
return OK;
}
</PRE>
<P><B>Note: </B>If this program were compiled and linked as an inboard module,
the global variables would have to be stored in the cache
and associated with the module ID.
Otherwise, the global variables would be shared among all calls to
the module.
<P><HR><B>[ <A HREF="#Top_Of_Page">Top of Page</A> | <A
HREF="progu040.htm">Previous Page</A> | <A HREF="progu042.htm">Next
Page</A> | <A HREF="../proguide.htm#ToC">Table of Contents</A> | <A
HREF="progu037.htm#PToC13">Partial Table of Contents</A> | <A
HREF="progu344.htm#HDRINDEX_START">Index</A> ]</B> <br><b>[<a
href="../allguide.htm">Data Explorer Documentation</a> | <a
href="../qikguide.htm">QuickStart Guide</a> | <a
href="../usrguide.htm">User's Guide</a> | <a
href="../refguide.htm">User's Reference</a> | <a
href="../proguide.htm">Programmer's Reference</a> | <a
href="../insguide.htm">Installation and Configuration
Guide</a> ]</b><br><p><b>[<a
href="http://www.research.ibm.com/dx">Data Explorer Home
Page</a>]</b><p><HR ALIGN=LEFT WIDTH=600><b>[<A
HREF="http://www.ibm.com/">IBM Home Page</A> | <A
HREF="http://www.ibm.com/Orders/">Order</A> | <A
HREF="http://www.ibm.com/Search/">Search</A> | <A
HREF="http://www.ibm.com/Assist/">Contact IBM</A> | <A
HREF="http://www.ibm.com/Legal/">Legal</A> ]</b><hr><p>
<A NAME="Bot_Of_Page"></A>
</BODY></HTML>
|